在旧应用程序中进行一些取证考古调查时,我必须保持这一点:
这是最近转换为.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 - 通过使用no-op委托调用线程(主gui)可以实现什么样的副作用。另外两个线程也在主gui线程上执行调用,但只有这个线程将优先级设置为除Normal之外的其他东西(它们使用Action而不是TreadStart)。
2 - 我的案例与这个应用程序奇怪地类似于死锁,有些东西告诉我这可能是原因。 (因为没有任何原因,在优先级和主要gui线程周围捣乱)。
由于
答案 0 :(得分:4)
此线程将导致调用函数阻塞,直到Dispatcher的线程可以“处理”(no-op)委托。
这可能不是一个好习惯,应该可以删除。我怀疑这里的目标是允许这个(第三个)BackgroundWorker
的完成事件成为前两个BackgroundWorker
完成时的信号。
一般来说,像这样完成旋转通常是设计糟糕的标志。一个更好的设计是使用CountdownEvent,BackgroundWorker
实例可以在完成时发出信号。
然后您可以等待倒计时事件,而不是使用Thread.Sleep
和调度程序调用进行循环。
答案 1 :(得分:2)
"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."
听起来似乎有道理。这段代码尖叫不好的做法和可能的死锁位置。由于代码引用了其他后台工作者,因此可能是其他人正在做类似的事情。现在,很明显某些东西是错误的,但是如果不知道发生了什么,就很难评论它是如何修复的。我的猜测是,这种方法存在一个基本的设计缺陷。