-2

我有一个可以取消的后台工作人员。

当 CancelPending 变量变为 true 时(响应 UI 上调用 worker.CancelAsynch() 的用户交互),正常流程会自行中断,抛出异常,因为如果那样(因为正常流程被中断,会抛出大量 null ref 异常)

因此,当工作人员返回时,我希望能够区分工作人员被取消时引发的异常(以静默方式忽略它们)和工作人员未被取消时引发的异常(将它们报告给 UI)。

我的代码如下(对不起 c#/vb 混合...):

工人阶级:

Public Class ClassBaseGetObjectsWorker
    Inherits System.ComponentModel.BackgroundWorker
    

 Protected Overrides Sub OnDoWork(ByVal e As System.ComponentModel.DoWorkEventArgs)
        Try

            Dim cpt As Int16 = 0
            While cpt < 5
                System.Threading.Thread.Sleep(1000)
                cpt = cpt + 1
                If CheckForCancellation() Then
                    'Simulating exception due to cancel
                    Throw New Exception("Exception du to cancel !")
                End If
            End While

        Catch exc As Exception
            e.Cancel = Me.CancellationPending
            Throw exc
        End Try

    End Sub
End Class

回电:

void setObjSetCollWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
    if (e.Cancelled) {
        resultLabel.Text += "Canceled";
        //e.Error is selently ignored
    }
    else {
        if (e.Error != null) {
            //Reporting errors arising during normal (uncanceled) flow
            throw e.Error.InnerException;
        }
        else {
            //Worker process finished without error or being canceled.
            updateUIAfterBackgroundJob();
        }
    }
}

然后,当我在执行 worker.CancelAsynch() 时,e.Cancelled 在 Completed 回调中设置为 false(这不是我所期望的)。如果我在工作人员中注释掉“Trow exc”,如果我再次测试,则 e.Cancelled 正确设置为 true。

获取我想要的信息的最干净的方法是什么,即:我想知道当worker处于cancellationPending状态时是否抛出了在完成处理程序中弹出的异常?

4

1 回答 1

1

如果在 OnDoWork() 实现中构建代码的最佳方式是在检测到取消时抛出异常,请执行以下操作:

创建一个 CancelException:

public class CancelException: Exception {}

当您检测到取消挂起时抛出此 CancelException:

if(CheckForCancellation()) throw new CancelException();

在 OnDoWork() 方法中的代码周围添加一个 try-catch:

protected override void OnDoWork(DoWorkEventArgs e){
  try{
    //...
  }
  catch(CancelException){
    // silently return
    return;
  }
}

这样,您的代码将遵守 BackgroundWorker 合同(当您检测到取消挂起时从 OnDoWork() 返回,而不是抛出异常),并且 Canceled 属性现在应该如您所愿

于 2009-06-26T12:17:30.427 回答