【问题标题】:Issues calling Dispatcher in WPF在 WPF 中调用 Dispatcher 的问题
【发布时间】:2009-02-06 00:04:29
【问题描述】:

我有一些 UI 代码需要从我的后台演示者线程中更新。 因此,我执行以下操作: 在我的后台线程中,我在 UI 中设置了我的属性:

_ui.ConnectionStatus = "A";

那么,我的设置如下:

public string ConnectionStatus
{
    set
    {
        if (Dispatcher.CheckAccess())
            ConnectionStatusTxt.Content = value;
        else
        {
            Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                              {ConnectionStatusTxt.Content = value;}));
        }
    }
}

我收到以下错误:

The calling thread cannot access this object because a different thread owns it.

我的理解是Dispatcher 负责调用不同的线程,所以这个错误让我有点困惑。 谢谢!

【问题讨论】:

  • 您确定这是来自用户控件的 Dispatcher 对象吗?错误发生在哪一行?
  • Patrick,我正在使用用户控件的调度程序。 Dispatcher 执行 ConnectionStatusTxt.Content = value; 时出现错误;
  • 采用哪个代码路径-您说当 Dispatcher 执行 ConnectionStatusTxt.Content = value 时发生错误,但您的意思是直接调用 if 语句的真实路径还是委托假路径?
  • 在错误的路径上,很抱歉造成混乱

标签: c# wpf multithreading dispatcher


【解决方案1】:

另一个问题:什么是值?这是一个字符串吗? 我可以想象错误可能是该值实际上是您创建的 UIElement(可能是标签?),在这种情况下,异常指的是值对象而不是您的用户控件。

【讨论】:

  • 该值确实是一个字符串。实际上,当我现在正在调试它时,传入字符串似乎是有效的;但是,当您将 ImageSource 传递给看起来相同的属性时(assignm 是 diff:TechIcon.Source = value;其中 Source 是 ImageSource)——现在不起作用。
  • 这很有意义,因为 ImageSource 是一个 DependencyObject,因此只能从创建它的 Thread 进行修改。如果您在后台线程中创建 ImageSource,这将不起作用。您需要在标准 UI 线程中创建 ImageSource。
  • 您也可以尝试冻结您的 ImageSource 对象。请参阅 Freezable 类的文档。线程安全:冻结的 Freezable 对象可以跨线程共享
  • Patrick,您最后的评论完全正确。一个我“冻结”了我的 ImageSource 对象,一切正常!谢谢!
【解决方案2】:

你没有说这个setter在里面执行的是什么对象,但是看起来这个对象的Dispatcher和ConnectionStatusTxt的dispatcher并不一样,即包含setter的对象是由与ConnectionStatusTxt控件不同的线程拥有的。

尝试在您的 CheckAccess 和 Invoke 语句中使用 ConnectionStatusTxt.Dispatcher。

【讨论】:

  • 我尝试使用 ConnectionStatusTxt 的调度程序,但没有成功。感谢您指出不一致的地方 - 我更新了我的帖子,希望它现在更有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 2016-12-03
相关资源
最近更新 更多