在我必须维护的旧应用程序中进行一些法医考古调查时,我遇到了这个:
它是一个最近转换为 .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 线程上执行调用,但只有这个线程将优先级设置为正常以外的其他内容(它们使用 Action 而不是 TreadStart)。
2 - 我的情况与此应用程序的死锁非常相似,并且某些事情告诉我这可能是原因。(无缘无故地围绕优先级和主 GUI 线程)。
谢谢
此线程将导致调用函数阻塞,直到调度程序的线程可以"处理"(无操作)委托。
这可能不是一个好的做法,可能应该删除。 我怀疑这里的目标是让这个(第三个)BackgroundWorker
的完成事件成为前两个BackgroundWorker
完成时的信号。
一般来说,像这样旋转完成通常是设计不佳的标志。 更好的设计是使用 CountdownEvent,它可以在完成时由两个BackgroundWorker
实例发出信号。
然后,您可以只等待倒计时事件,而不是循环使用 Thread.Sleep
和调度程序调用。
-
"What possible side-effect would be acheived by [...]"
因为它使用Invoke
而不是BeginInvoke
所以它将是一个阻止调用。 这意味着在您的 noop 委托运行之前,您的后台线程不会继续执行。 其效果是,在执行此 noop 之前排队进入消息循环的所有内容之前,代码不会继续。 -
"I have cases that strangely resembles deadlock with this application and something tells me that this could be the cause."
对我来说听起来很有道理。 此代码块既会指出不良做法,也会引发可能的死锁位置。 由于代码引用了其他后台工作线程,因此可能是其他人正在执行类似操作。
现在,似乎很明显出了问题,但是如果不了解更多有关正在发生的事情的信息,就很难评论如何解决它。 我的猜测是,正在采取的方法存在根本的设计缺陷。