3

在我必须维护的旧应用程序中进行一些取证考古调查时,我遇到了这个:

这是一个最近转换为 .NET 4.0 的 WPF 应用程序,此代码在后台工作程序中运行

           if(bgWorker1.IsBusy || bgWorker2.IsBusy)
           {
                Thread.Sleep(100); 
                Application.Current.Dispatcher.Invoke(
                    System.Windows.Threading.DispatcherPriority.Background, 
                    new System.Threading.ThreadStart(delegate { })
                );
           }

1 - 通过使用无操作委托调用线程(主 gui)可以实现什么可能的副作用。其他两个线程也在主 gui 线程上执行调用,但只有这个线程将优先级设置为 Normal 以外的其他内容(尽管它们使用 Action 而不是 TreadStart)。

2 - 我有一些奇怪地类似于此应用程序死锁的案例,并且有些事情告诉我这可能是原因。(无缘无故地绕过优先级和主 gui 线程)。

谢谢

4

2 回答 2

5

该线程将导致调用函数阻塞,直到 Dispatcher 的线程可以“处理”(无操作)委托。

这可能不是一个好的做法,应该删除。我怀疑这里的目标是让这个(第三个)BackgroundWorker的完成事件成为前两个BackgroundWorker完成的信号。

一般来说,像这样旋转完成通常是糟糕设计的标志。更好的设计是使用CountdownEventBackgroundWorker ,两个实例在完成时都可以发出信号。

然后,您可以等待倒计时事件,而不是循环Thread.Sleep调用调度程序。

于 2012-10-15T20:40:36.177 回答
2
  1. "What possible side-effect would be acheived by [...]"因为它使用Invoke而不是BeginInvoke它将是一个阻塞调用。这意味着在您的 noop 委托运行之前,您的后台线程不会继续执行。效果是代码不会继续,直到在执行此 noop 之前排队进入消息循环的所有内容。
  2. "I have cases that strangely resembles deadlock with this application and something tells me that this could be the cause." 对我来说听起来很合理。这段代码既说明了不好的做法,也说明了可能的死锁位置。由于代码引用了其他后台工作人员,因此其他人可能正在做类似的事情。

现在,似乎很明显有些地方出了问题,但是在不了解发生了什么的情况下,很难评论如何修复它。我的猜测是,尽管采用的方法存在一个基本的设计缺陷。

于 2012-10-15T20:41:28.627 回答