C#具有助手功能的后台工作人员取消

C#具有助手功能的后台工作人员取消,c#,multithreading,backgroundworker,cancellation,C#,Multithreading,Backgroundworker,Cancellation,通常,当我想取消C#中的后台工作人员时,我会这样做: while (backgroundWorker1.IsBusy) { backgroundWorker1.CancelAsync(); autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT); } 在一个应用程序中,有许多后台工作人员。像这样使用helper函数取消backgroundWorkers有效吗 CancelBackgroundWorke

通常,当我想取消C#中的后台工作人员时,我会这样做:

     while (backgroundWorker1.IsBusy)
     {
        backgroundWorker1.CancelAsync();
        autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT);
     }
在一个应用程序中,有许多后台工作人员。像这样使用helper函数取消backgroundWorkers有效吗

CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are)
{
     while (bgw.IsBusy)
     {
        bgw.CancelAsync();
        are.WaitOne(BGW_CANCEL_TIMEOUT);
     }
}
我担心的是,不是将有问题的对象传递到函数中,而是复制,从而破坏了函数的目的。使用该函数的主要目的是减少代码空间,使应用程序代码更具可读性/可维护性。

您的代码是错误的

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


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

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


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

是的,我意识到这一点。我的backgroundWorker已签入以查找backgroundWorker1.CancellationPending并相应退出。我的问题更多的是,backgroundWorker1标志是由helper函数设置的,还是将设置backgroundWorker副本的标志,该副本在函数返回时被销毁。因为
backgroundWorker
类不是一个结构,不是。所有C#类都是通过引用传递的。但是,该函数是无用的。除非使用ref或out关键字,否则类是按值传递的。对于引用类型,传递引用的副本。@Chris:类通过引用传递;引用是按值传递的。也许可以更清楚地说,对类实例的引用是按值传递的。对我来说,说类是通过引用传递的是令人困惑的。为了其他人的利益,我参考Jon Skeet的文章: