WPF Dispatcher {“调用线程不能访问这个对象,因为一个不同的线程拥有它。”}
首先,我需要说我很喜欢WPF和C#。 应用程序:创建曼德尔布罗图片(GUI) 我分派工作完全此这种情况下:WPF Dispatcher {“调用线程不能访问这个对象,因为一个不同的线程拥有它。”}
private void progressBarRefresh(){
while ((con.Progress) < 99)
{
progressBar1.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate
{
progressBar1.Value = con.Progress;
}
));
}
}
我得到的消息(标题)特林当与下面的代码来做到这一点:
bmp = BitmapSource.Create(width, height, 96, 96, pf, null, rawImage, stride);
this.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate
{
img.Source = bmp;
ViewBox.Child = img; //vllt am schluss
}
));
我将尝试解释我的程序如何工作。 我创建了一个新的线程(因为GUI不响应)来计算像素和颜色。在这个线程(方法)中,在计算准备就绪后,我使用Dispatcher刷新ViewBox中的图像。
当我不把计算放在单独的线程中时,我可以刷新或构建我的图像。
您正在您的worker(?)线程上创建位图(bmp
),然后将它传递给UI线程 - 这是失败的。
您需要在UI线程上创建图像。您可能需要某种方法来引用您想要显示的图像,并将信息传递给UI。
MSDN说:“冻结的Freezable可以跨线程共享。”
也许这线程将帮助:http://social.msdn.microsoft.com/Forums/en-US/windowswic/thread/9223743a-e9ae-4301-b8a4-96dc2335b686
你也可以使用一个排队机制在线程之间传递消息。毕竟,这就是Windows架构的工作原理。这就是调度员正在做的事情。您正将一个引用传递给该委托,该委托不属于WPF线程。
所以,是的,你有基本的想法,但实际上你需要使用Action<T>(T object)
传位给其他线程,或在您的情况:
Dispatcher.Invoke(DispatcherPriority.Send, new Action<Bitmap>(delegate(Bitmap img) {
do things here...
}), bmp);
不会有所作为,您仍然共享被引用的对象。 – 2010-06-06 02:19:19
万一你希望对象是在不同线程之间共享,然后总是在UI线程上创建该对象。稍后,当您想要访问该对象时,可以检查是否有权访问该对象。如果您没有访问权限,请通过UI线程访问重新调用该函数。下面的示例代码:
private void YourMethod()
{
if (Application.Current.Dispatcher.CheckAccess())
{
// do whatever you want to do with shared object.
}
else
{
//Other wise re-invoke the method with UI thread access
Application.Current.Dispatcher.Invoke(new System.Action(() => YourMethod()));
}
}
当你得到一个Dispatcher
你会得到一个不同的每一个不同的线程。
this.Dispatcher
可能会给你另一个Dispatcher而不是UI,所以你会得到那个错误。
尝试使用Application.Current.Dispatcher
代替,这将始终返回UI线程的分派器。
如果您从其他线程使用Dispatcher.CurrentDispatcher
,则可能会发生同样的错误。
您不需要在UI线程上创建图像。你不能从一个线程在另一个线程上使用它(而.NET假定除非你将它标记为* freeze *,否则它将被再次修改)。 – 2010-06-06 02:18:33