WPF Dispatcher {“调用线程无法访问此对象,因为另一个线程拥有它。”}

首先,我需要说我是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中刷新我的图像。

当我不将计算放在单独的线程中时,我可以刷新或构建我的图像。

如果您希望在不同线程之间共享该对象,则始终在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())); } } 

MSDN说:“冻结的Freezable可以跨线程共享。”

也许这个主题会有所帮助: http : //social.msdn.microsoft.com/Forums/en-US/windowswic/thread/9223743a-e9ae-4301-b8a4-96dc2335b686

获得Dispatcher ,每个不同的线程都会得到一个不同的Dispatcher

this.Dispatcher可能会给你另一个Dispatcher而不是UI,所以你得到了那个错误。

请尝试使用Application.Current.Dispatcher ,这将始终返回UI线程的Dispatcher。

如果您从另一个线程使用Dispatcher.CurrentDispatcher ,则可能会发生同样的错误。

你正在你的worker(?)线程上创建位图( bmp )然后将它传递给UI线程 – 这就是失败。

您需要在UI线程上创建图像。 您可能需要某种方式来引用要显示的图像并将信息传递给UI。

您还可以使用排队机制在线程之间传递消息。 毕竟,这就是Windows架构的工作原理。 这就是调度员正在做的事情。 您正在将引用传递给委托,该委托不归WPF线程所有。

所以,是的,你有基本的想法,但你需要通过使用Action(T object)实际将位图传递给另一个线程,或者在你的情况下:

 Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate(Bitmap img) { do things here... }), bmp);