Dar*_*Zon 9 c# wpf dispatcher backgroundworker dispatch
我在WPF应用程序中的后台工作者中意识到了一些奇怪的东西.
我现在想要完成的是等到BW完成另一个线程.
检查以下代码:
if (bw.IsBusy)
{
bw.CancelAsync();
System.Threading.ThreadStart WaitThread =
new System.Threading.ThreadStart(delegate() {
while (bw.IsBusy)
{
System.Threading.Thread.Sleep(100);
}
bw.RunWorkerAsync();
});
System.Windows.Application.Current.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
WaitThread); // if I remove this line, bw fires RunWorkerAsyncEvent
}
else
{
bw.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
请注意,我添加了一个Dispatcher.Invoke,等到bw不忙,但如果我调用它并且从不触发RunWorkerAsyncCompleted事件,则所有时间都很忙.虽然,如果我删除该行,FIRES事件,这真的很奇怪.
我怎么能等到bw结束?
Han*_*ant 25
这称为"死锁",这是一个非常常见的线程问题.在运行RunWorkerCompleted事件之前,BGW无法停止忙碌.该事件在您的应用程序的主线程上运行,它只能在您的主线程不忙于执行其他操作时运行.它必须是空闲的,在调度程序循环内运行.
但是你的主线程没有空闲,它被卡在while()循环内等待IsBusy返回false.所以事件永远不会运行,因为主线程忙于等待BGW完成,BGW无法完成,因为主线程永远不会空闲."致命的拥抱",又名死锁.
你必须以不同的方式做到这一点,你不能等待.比如创建另一个BGW实例.或者只是在RWC事件触发之前不允许此代码运行.或者通过设置一个标志,由RunWorkerCompleted事件处理程序测试,然后可以再次启动BGW.
死锁的发生是由于应用程序的“主”线程无法运行(并处理事件),因此后台工作程序永远无法触发其完成的功能。您可以做的就是添加一个 Application.DoEvents(); 来允许应用程序触发此事件。
这就是我目前在类似场景中使用的方法,它看起来很有魅力!
while (bw.IsBusy)
{
Application.DoEvents();
System.Threading.Thread.Sleep(100);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18769 次 |
| 最近记录: |