通常,当我想在C#中取消backgroundWorker时,我会做这样的事情:
while (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT);
}
在一个应用程序中有许多背景工作者。使用辅助函数取消backgroundWorkers是否有效?
CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are)
{
while (bgw.IsBusy)
{
bgw.CancelAsync();
are.WaitOne(BGW_CANCEL_TIMEOUT);
}
}
我担心的是,不是将有问题的对象传递给函数,而是复制,从而破坏了具有该功能的目的。拥有该函数的主要目的是减少代码空间并使应用程序代码更易读/可维护。
答案 0 :(得分:2)
不,这不行。当BGW具有RunWorkerCompleted事件处理程序时,它会导致死锁。在主线程空闲并重新进入消息循环之前,该处理程序无法运行。在该事件处理程序完成之前,IsBusy属性将保持为True。
您在WaitOne呼叫上超时,因此至少您的程序不会完全挂起。但是当WaitOne()返回时,BGW 尚未尚未完成,RWC事件处理程序尚未运行。唯一可行的替代方案是让RWC事件处理程序完成取消完成后所做的任何事情。
答案 1 :(得分:0)
你的代码错了。
调用CancelAsync
只会将BackgroundWorker上的CancellationPending
flag设置为true
。 DowWork
事件中的代码应定期检查此标志,并在标志为true
时停止。
多次调用CancelAsync
将没有任何好处,并且在实际取消之前不应该有任何理由冻结UI线程。