0

通常,当我想在 C# 中取消 backgroundWorker 时,我会执行以下操作:

     while (backgroundWorker1.IsBusy)
     {
        backgroundWorker1.CancelAsync();
        autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT);
     }

在一个应用程序中,有许多 backgroundWorker。像这样使用辅助函数来取消 backgroundWorkers 是否有效?

CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are)
{
     while (bgw.IsBusy)
     {
        bgw.CancelAsync();
        are.WaitOne(BGW_CANCEL_TIMEOUT);
     }
}

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

4

2 回答 2

2

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

您的 WaitOne 调用超时,因此至少您的程序不会完全挂起。但是当 WaitOne() 返回时,BGW 还没有完成,RWC 事件处理程序还没有运行。唯一可行的替代方法是让 RWC 事件处理程序在取消完成后执行任何需要完成的操作。

于 2010-07-12T14:51:06.900 回答
0

你的代码是错误的。

调用CancelAsync只是将BackgroundWorker 上的CancellationPending标志true设置为. 您的DowWork事件中的代码应定期检查此标志,如果标志为 ,则停止true

多次调用CancelAsync不会有任何好处,并且不应该有任何理由冻结 UI 线程,直到它实际取消。

于 2010-07-12T14:44:43.770 回答