当前位置:  开发笔记 > 编程语言 > 正文

WPF Dispatcher.Invoke'hanging'

如何解决《WPFDispatcher.Invoke'hanging'》经验,为你挑选了3个好方法。

我有一个有点复杂的WPF应用程序,当尝试使用调度程序在UI线程上调用调用时,似乎是"挂起"或卡在Wait调用中.

一般过程是:

    处理按钮上的单击事件

    创建一个新线程(STA),其中:创建演示者和UI的新实例,然后调用Disconnect方法

    断开然后在名为Name的UI上设置属性

    然后,Name的setter使用以下代码来设置属性:

    if(this.Dispatcher.Thread != Thread.CurrentThread)
    {
        this.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate{
            this.Name = value; // Call same setter, but on the UI thread
        });
        return;
    }

    SetValue(nameProperty, value); // I have also tried a member variable and setting the textbox.text property directly.

我的问题是,当调用 dispatcher invoke方法时,它似乎每次都挂起,并且callstack指示它处于休眠状态,等待或加入Invoke实现.

那么,有什么我做错了,我错过了,显而易见或没有,或者有更好的方法调用UI线程来设置这个属性(和其他)?

编辑:解决方案是在线程委托的末尾调用System.Windows.Threading.Dispatcher.Run()(例如,正在执行工作的地方) - 感谢所有帮助过的人.



1> Ana Betts..:

调用是同步的 - 您需要Dispatcher.BeginInvoke.另外,我相信你的代码示例应该在"else"语句中移动"SetValue".



2> Alexandru..:

我认为这可以通过代码更好地显示出来.考虑这种情况:

线程A执行此操作:

lock (someObject)
{
   // Do one thing.
   someDispatcher.Invoke(() =>
   {
      // Do something else.
   }
}

线程B执行此操作:

someDispatcher.Invoke(() =>
{
   lock (someObject)
   {
      // Do something.
   }
}

乍一看,一切看起来都很精致,但事实并非如此.这将产生僵局.调度程序就像一个线程的队列,当处理像这样的死锁时,以这种方式思考它们很重要:"以前的调度可能会阻塞我的队列?".线程A将进入...并在锁定下发送.但是,如果线程B在标记为"做一件事"的代码中的线程A进入的时候会怎样?好...

线程A锁定someObject并运行一些代码.

线程B现在调度,并且调度程序将尝试获取某个对象的锁定,从而干扰您的调度程序,因为线程A已经具有该锁定.

然后,线程A将排队另一个调度项.永远不会触发此项目,因为您的调度员永远不会完成处理您之前的请求; 它已经卡住了.

你现在有一个漂亮的僵局.



3> Keith..:

你说你正在创建一个新的STA线程,这个新线程运行的调度程序是什么?

我是从"this.Dispatcher.Thread!= Thread.CurrentThread"得到的,你希望它是一个不同的调度员.确保它运行,否则它不会处理它的队列.

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有