使用帮助函数取消C#BackgroundWorker

时间:2010-07-12 14:39:31

标签: c# multithreading backgroundworker cancellation

通常,当我想在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);
     }
}

我担心的是,不是将有问题的对象传递给函数,而是复制,从而破坏了具有该功能的目的。拥有该函数的主要目的是减少代码空间并使应用程序代码更易读/可维护。

2 个答案:

答案 0 :(得分:2)

不,这不行。当BGW具有RunWorkerCompleted事件处理程序时,它会导致死锁。在主线程空闲并重新进入消息循环之前,该处理程序无法运行。在该事件处理程序完成之前,IsBusy属性将保持为True。

您在WaitOne呼叫上超时,因此至少您的程序不会完全挂起。但是当WaitOne()返回时,BGW 尚未尚未完成,RWC事件处理程序尚未运行。唯一可行的替代方案是让RWC事件处理程序完成取消完成后所做的任何事情。

答案 1 :(得分:0)

你的代码错了。

调用CancelAsync只会将BackgroundWorker上的CancellationPending flag设置为trueDowWork事件中的代码应定期检查此标志,并在标志为true时停止。

多次调用CancelAsync将没有任何好处,并且在实际取消之前不应该有任何理由冻结UI线程。