首先,我需要说我是WPF和C#的菜鸟。 应用:创建Mandelbrot图像(GUI) 我的调度员完全适用于这种情况:
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
}
));
我将尝试解释我的程序是如何工作的。 我创建了一个新的Thread(因为GUI不响应)来计算像素和颜色。在这个线程(方法)中,我在计算准备好后使用Dispatcher在ViewBox中刷新我的图像。
当我不将计算放在单独的线程中时,我可以刷新或构建我的图像。
答案 0 :(得分:25)
如果您希望在不同线程之间共享该对象,则始终在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()));
}
}
答案 1 :(得分:7)
MSDN说:“冻结的Freezable可以在线程之间共享。”
也许这个帖子会有所帮助:http://social.msdn.microsoft.com/Forums/en-US/windowswic/thread/9223743a-e9ae-4301-b8a4-96dc2335b686
答案 2 :(得分:3)
当你得到一个Dispatcher
时,你会得到一个不同的线程。
this.Dispatcher
可能会为您提供另一个Dispatcher而不是UI,因此您会收到该错误。
尝试使用Application.Current.Dispatcher
,这将始终返回UI线程的Dispatcher。
如果您使用其他线程中的Dispatcher.CurrentDispatcher
,可能会发生同样的错误。
答案 3 :(得分:2)
你正在你的worker(?)线程上创建位图(bmp
),然后将其传递给UI线程 - 这就是失败。
您需要在UI线程上创建图像。您可能需要某种方式来引用要显示的图像,并将 信息传递给UI。
答案 4 :(得分:2)
您还可以使用排队机制在线程之间传递消息。毕竟,这就是Windows架构的工作原理。这就是调度员正在做的事情。您正在将引用传递给委托,该委托不属于WPF主题。
所以是的,你有基本的想法,但你需要使用Action<T>(T object)
实际将位图传递给另一个线程,或者在你的情况下:
Dispatcher.Invoke(DispatcherPriority.Send, new Action<Bitmap>(delegate(Bitmap img) {
do things here...
}), bmp);