gpt4 book ai didi

c# - 从 WPF 中的不同线程更新 UI 控件时出现 "The calling thread cannot access this object because a different thread owns it"错误

转载 作者:行者123 更新时间:2023-11-30 21:43:12 26 4
gpt4 key购买 nike

我有从主线程调用的方法。此方法正在创建一个新线程。代码如下所示:

MouseCursorWallObject MouseCursorWall = null;
List<MovingRectangle> MovingRectangles = null;

DrawingImage RenderedImage;


public MainWindow()
{
InitializeComponent();
PrepareObjects();
GameLoopRun();
}

private void GameLoopRun()
{
Thread thread = new Thread(() =>
{
while (true)
{
DateTime dtStart = DateTime.Now;

Events();
Update();
Display();

DateTime dtEnd = DateTime.Now;
TimeSpan ts = dtEnd - dtStart;
if (SkipTicks - ts.TotalMilliseconds >= 0)
{
Thread.Sleep((int)(SkipTicks - ts.TotalMilliseconds));
}
}
});
thread.Start();
}

在 Display() 方法中,我正在尝试更新图像控件。 “Display()”方法如下所示:

private void Display()
{
DrawingGroup imageDrawings = new DrawingGroup();

// Drawing main canvas
imageDrawings.Children.Add(DrawingObject(500, 350, 0, 0, new Uri(@"Images\gameCanvas.jpg", UriKind.Relative)));

// Drawing mouse cursor wall
imageDrawings.Children.Add(DrawingObject(MouseCursorWall.Width, MouseCursorWall.Height, MouseCursorWall.GetLocX, MouseCursorWall.GetLocY, MouseCursorWall.DisplayTexture));

for (int i = 0; i < MovingRectangles.Count; i++)
{
MovingRectangle o = MovingRectangles[i];

// Drawing moving object
imageDrawings.Children.Add(DrawingObject(20, 20, o.GetLocX, o.GetLocY, o.TextureUri));
}

if (GamePause == true)
{

}
RenderedImage = new DrawingImage(imageDrawings);

// Image control on main UI thread
renderImage.Dispatcher.Invoke(() =>
{
renderImage.Source = RenderedImage;
});
}

问题是当我尝试使用 Dispatcher.Invoke 更新图像控件时,我收到错误“调用线程无法访问此对象,因为另一个线程拥有它”。我尝试了很多不同的选项,但只有一个效果很好:

private void Display()
{
this.Dispatcher.Invoke(() => {
DrawingGroup imageDrawings = new DrawingGroup();

// Drawing main canvas
imageDrawings.Children.Add(DrawingObject(500, 350, 0, 0, new Uri(@"Images\gameCanvas.jpg", UriKind.Relative)));

// Drawing mouse cursor wall
imageDrawings.Children.Add(DrawingObject(MouseCursorWall.Width, MouseCursorWall.Height, MouseCursorWall.GetLocX, MouseCursorWall.GetLocY, MouseCursorWall.DisplayTexture));

for (int i = 0; i < MovingRectangles.Count; i++)
{
MovingRectangle o = MovingRectangles[i];

// Drawing moving object
imageDrawings.Children.Add(DrawingObject(20, 20, o.GetLocX, o.GetLocY, o.TextureUri));
}

if (GamePause == true)
{

}

RenderedImage = new DrawingImage(imageDrawings);
renderImage.Source = RenderedImage;
});

}

您能解释一下为什么“Display()”方法的第二个选项工作正常,但第一个选项抛出异常吗?我做错了什么?

最佳答案

DrawingImageDrawingGroup 都继承自 DispatcherObject ,这意味着需要从创建它们的线程访问它们。这就是为什么您的所有工作都被调用回调度程序的版本可以正常工作的原因。

正如 Brian Reichle 所指出的,这些对象也继承自 System.Windows.Freezable ,您可以利用它来允许跨线程访问对象。

关于c# - 从 WPF 中的不同线程更新 UI 控件时出现 "The calling thread cannot access this object because a different thread owns it"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41915148/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com