【问题标题】:WPF Dispatcher {"The calling thread cannot access this object because a different thread owns it."}WPF Dispatcher {“调用线程无法访问此对象,因为不同的线程拥有它。”}
【发布时间】:2010-06-05 23:17:59
【问题描述】:

首先我需要说我是 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
            }
          ));

我将尝试解释我的程序是如何工作的。 我创建了一个新线程(因为 GUI 不响应)来计算像素和颜色。在这个线程(方法)中,计算准备好后,我正在使用调度程序刷新 ViewBox 中的图像。

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

【问题讨论】:

    标签: c# wpf dispatcher


    【解决方案1】:

    以防万一您希望在不同线程之间共享对象,请始终在 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()));
            }
        }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        当您收到Dispatcher 时,您会为每个不同的线程获得一个不同的。

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

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

        当然,如果您在另一个线程中使用Dispatcher.CurrentDispatcher,也可能会发生同样的错误。

        【讨论】:

          【解决方案4】:

          您正在您的 worker(?) 线程上创建位图 (bmp),然后将其传递给 UI 线程 - 这就是失败的原因。

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

          【讨论】:

          • 您不需要在 UI 线程上创建图像。当它在另一个线程上被修改时,您不能从一个线程中使用它(并且.NET 假设除非您将其标记为 frozen,否则它将再次被修改)。
          【解决方案5】:

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

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

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

          【讨论】:

          • 不会有什么不同,您仍在共享被引用的对象。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-13
          • 2012-06-03
          • 1970-01-01
          • 1970-01-01
          • 2022-01-13
          相关资源
          最近更新 更多