C# &引用;调用线程无法访问此对象,因为其他线程拥有它";从WPF中的不同线程更新UI控件时出错
我有一个从主线程调用的方法。此方法正在创建新线程。代码如下所示:C# &引用;调用线程无法访问此对象,因为其他线程拥有它";从WPF中的不同线程更新UI控件时出错,c#,wpf,multithreading,invoke,dispatcher,C#,Wpf,Multithreading,Invoke,Dispatcher,我有一个从主线程调用的方法。此方法正在创建新线程。代码如下所示: MouseCursorWallObject MouseCursorWall = null; List<MovingRectangle> MovingRectangles = null; DrawingImage RenderedImage; public MainWindow() { InitializeComponent(); PrepareObjects();
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();
}
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;
});
}
MouseCursorWall对象MouseCursorWall=null;
列表移动矩形=空;
绘制图像渲染图像;
公共主窗口()
{
初始化组件();
准备对象();
GameLoopRun();
}
私有void GameLoopRun()
{
线程线程=新线程(()=>
{
while(true)
{
DateTime dtStart=DateTime.Now;
事件();
更新();
显示();
DateTime dtEnd=DateTime.Now;
TimeSpan ts=dtEnd-dtStart;
如果(SkipTicks-ts.total毫秒>=0)
{
睡眠((int)(SkipTicks-ts.total毫秒));
}
}
});
thread.Start();
}
在Display()方法中,我正在尝试更新图像控件。“Display()”方法如下所示:
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();
}
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;
});
}
private void Display()
{
DrawingGroup imageDrawings=新建DrawingGroup();
//绘制主画布
添加(DrawingObject(500350,0,0,新Uri(@“Images\gameCanvas.jpg”,UriKind.Relative));
//绘制鼠标光标墙
imageDrawings.Children.Add(DrawingObject(MouseCursorWall.Width,MouseCursorWall.Height,MouseCursorWall.GetLocX,MouseCursorWall.GetLocY,MouseCursorWall.DisplayTexture));
对于(int i=0;i
{
renderImage.Source=renderImage;
});
}
问题是,当我尝试使用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;
});
}
private void Display()
{
this.Dispatcher.Invoke(()=>{
DrawingGroup imageDrawings=新建DrawingGroup();
//绘制主画布
添加(DrawingObject(500350,0,0,新Uri(@“Images\gameCanvas.jpg”,UriKind.Relative));
//绘制鼠标光标墙
imageDrawings.Children.Add(DrawingObject(MouseCursorWall.Width,MouseCursorWall.Height,MouseCursorWall.GetLocX,MouseCursorWall.GetLocY,MouseCursorWall.DisplayTexture));
对于(int i=0;i
您能解释一下为什么“Display()”方法的第二个选项工作正常,但第一个选项引发异常吗?我做错了什么?绘图图像和绘图组都继承自,这意味着需要从创建它们的线程访问它们。这就是为什么将所有工作调用回dispatcher的版本能够正常工作的原因
正如Brian Reichle所指出的,这些对象也从中继承,您可以利用它来允许跨线程访问对象。我已经找到了这个主题。好的,如果您先冻结DrawingImage,您可能可以使用第一个示例,但您可能应该在UI线程上创建它(根据您的第二个示例).谢谢你的回复!我现在要检查一下。”…从DispatcherObject继承,这意味着需要从创建它们的线程访问它们。”。。。除非它们碰巧被冻住了。