【问题标题】:C# BackgroundWorker Cancellation with Helper FunctionC# BackgroundWorker 取消与帮助函数
【发布时间】:2011-03-14 20:29:27
【问题描述】:

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

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

【问题讨论】:

    标签: c# multithreading backgroundworker cancellation


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      你的代码错了。

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

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

      【讨论】:

      • 是的,我意识到这一点。我的 backgroundWorker 已检查它以查找 backgroundWorker1.CancellationPending 并相应地退出。我的问题更重要的是,backgroundWorker1 标志将由辅助函数设置,还是将设置 backgroundWorker 副本的标志,该副本在函数返回时被销毁。
      • 因为BackgroundWorker 类不是结构,所以不。所有 C# 类始终通过引用传递。不过这个功能没用。
      • 类是按值传递的,除非使用了 ref 或 out 关键字。对于引用类型,传递引用的副本。
      • @Chris:类是通过引用传递的;引用是按值传递的。
      • 也许更清楚地说,对类实例的引用是按值传递的。对我来说,说类是通过引用传递是令人困惑的。为了他人的利益,我参考了 Jon Skeet 的文章:yoda.arachsys.com/csharp/parameters.html
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2011-08-07
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多