Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Backgroundworker:取消期间发生异常_C#_Multithreading_Exception_Backgroundworker - Fatal编程技术网

C# Backgroundworker:取消期间发生异常

C# Backgroundworker:取消期间发生异常,c#,multithreading,exception,backgroundworker,C#,Multithreading,Exception,Backgroundworker,我有一个背景工人,可以取消 当CancelPending变量变为true时,正常流中断自身(响应调用worker.CancelAsynch()的UI上的用户交互),会引发异常,因为如果这样(由于正常流中断,会引发大量null ref异常) 所以,当工作者返回时,我希望能够区分工作者返回时抛出的异常 已从未取消工作进程时引发的异常中取消(以静默方式忽略它们)(以向UI报告它们) 我的代码如下(很抱歉c#/vb混合使用…): 工人阶级: Public Class ClassBaseGetObject

我有一个背景工人,可以取消

当CancelPending变量变为true时,正常流中断自身(响应调用worker.CancelAsynch()的UI上的用户交互),会引发异常,因为如果这样(由于正常流中断,会引发大量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
然后,当我执行worker.CancelAsynch()时,在完成的回调中将e.Cancelled设置为false(这不是我所期望的)。如果我在worker中注释掉“Trow exc”,如果我再次测试,e.Cancelled正确设置为true


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

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

创建取消异常:

public class CancelException: Exception {}
检测到取消挂起时引发此CancelException:

if(CheckForCancellation()) throw new CancelException();
在OnDoWork()方法中的代码周围添加一个try catch:


这样,您的代码将遵守BackgroundWorker约定(即在检测到取消挂起时从OnDoWork()返回,而不是抛出异常),并且Cancelled属性现在应该如您所期望的那样,它是如何处理被取消的?worker与上面的模拟代码类似:它经历了几个级别的函数调用,如果CancellationPending(通过委托检查)变为true,则每个执行循环都将退出。考虑到流被中断且结果将被丢弃的事实,这些提前退出的循环和函数会导致“正常”的异常。为什么要问这个问题?一个不太好的选择是在我的BackgroundWorker派生类中添加一个公共成员“wascelected”,该类可以在OnDoWork catch块中设置为true(Me.wascelected=Me.CancellationPending)。然后可以在完成的回调中使用此成员。
if(CheckForCancellation()) throw new CancelException();
protected override void OnDoWork(DoWorkEventArgs e){
  try{
    //...
  }
  catch(CancelException){
    // silently return
    return;
  }
}