【问题标题】:Updating image via Dispatcher still gives "different thread owns it" error通过 Dispatcher 更新图像仍然给出“不同的线程拥有它”错误
【发布时间】:2014-02-19 20:19:06
【问题描述】:

我正在尝试从不同线程中的事件更新我的 UI 中的图像。我正在使用调度程序(基于此问题:Fire events from different thread)来执行此操作,但仍然得到“调用线程无法访问此对象,因为不同的线程拥有它”-i.Source = s; 处的错误消息。这样做的正确方法是什么?

void OnEvent(object sender, EventArgs e)
{
    ImageSource s = e.Image;
    Dispatcher.BeginInvoke((Action)(
        () => UpdateUI(myImage, s)
    ));
}

void UpdateUI(Image i, ImageSource s)
{
    i.Source = s;
}

非常感谢您的任何建议!

【问题讨论】:

  • 您在当前线程上调度,而不是 UI 线程。您首先需要访问 UI 线程调度程序。您从哪种对象中调度?

标签: c# wpf multithreading dispatcher


【解决方案1】:

在后台线程中创建的 ImageSource 不能作为源分配给 UI 控件。

您可以访问myImage.Dispatcher 以获取与图像控件关联的实际调度程序:

myImage.Dispatcher.BeginInvoke((Action)delegate       
  {
     ImageSource s = e.Image;
     UpdateUI(myImage, s);
  });

或

在分配之前致电ImageSource 上的Freeze()。冻结对象可以跨线程访问。

【讨论】:

  • 谢谢,我设法使用Freeze() 和ImageSource s = e.Image.Clone(); 完成了它。使用 myImage.Dispatcher 没有任何帮助。
  • 太棒了..!!那是为了以防Dispatcher 不正确。主要问题是我在答案中添加为粗体的问题。
【解决方案2】:

您收到此错误是因为您 ImageSource 已在与您要使用它的线程不同的线程上创建。您可以通过在您的 ImageSource 上调用 Freeze() 来修复它

ImageSource s = e.Image;
s.Freeze();

【讨论】:

  • 谢谢,我设法使用 Freeze() 和 ImageSource s = e.Image.Clone();
【解决方案3】:

您在当前线程上调度,而不是 UI 线程。您首先需要访问 UI 线程调度程序。使用

Application.Current.Dispatcher.BeginInvoke(...)

改为。

另请参阅此问题:How do I get the UI thread Dispatcher?

【讨论】:

  • 使用 Application.Current.Dispatcher myImage.Dispatcher 并没有改善任何东西。我现在选择Freeze()。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2015-11-16
  • 1970-01-01
相关资源
最近更新 更多