BackgroundWorker RunWorkerCompleted in Component

时间:2010-06-01 16:41:17

标签: .net backgroundworker

我熟悉以下内容:

“如果操作引发了代码无法处理的异常,则BackgroundWorker会捕获异常并将其传递给RunWorkerCompleted事件处理程序,并将其作为System.ComponentModel.RunWorkerCompletedEventArgs的Error属性公开。如果您正在运行在Visual Studio调试器下,调试器将在DoWork事件处理程序中出现未处理的异常的位置处断开。“

然而,我遇到了一个奇怪的故障。

在我的组件中,有一个BackgroundWorker实例。

即使它没有在调试器中运行,工作人员仍然无法处理异常。

即使是简化的代码也会产生未处理的异常(并且RunWorkerCompleted不会触发):

Throw New ArgumentException("Test")

主要是RunWorkerComplete的代码:

RaiseEvent UpdateComplete(Me, New AsyncCompletedEventArgs(e.Error, e.Cancelled, e.Result))

我需要组件通过公共事件公开worker异常。

如果我删除了RaiseEvent调用,该异常将由worker处理,并可通过e.Error访问。

显然,举起一个事件会导致工人错过这个例外。怎么会这样?

完整代码:

组件:

Private Sub workerDownloader_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)

        RaiseEvent UpdateComplete(Me, New AsyncCompletedEventArgs(e.Error, e.Cancelled, e.Result))

End Sub

Private Sub workerDownloader_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
        Throw New ArgumentException("Test")
End Sub

主机应用(WinForms):

Private Sub Connector1_UpdateComplete(ByVal sender As System.Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles Connector1.UpdateComplete
        If e.Error IsNot Nothing Then MessageBox.Show(e.Error.ToString)
End Sub

2 个答案:

答案 0 :(得分:2)

可能是你的e.Result正在抛出自己的异常。

来自the MSDN documentation on RunWorkerCompletedEventArgs

  

您的RunWorkerCompleted活动   处理程序应该经常检查   ErrorCancelled属性   在访问Result之前   属性。如果引发异常   或者如果操作被取消,   访问Result属性引发   例外。

具体来说,它会引发TargetInvocationException

在您发布的代码中,您正在通过AsyncCompletedEventArgs事件传递的参数构建新的RunWorkerCompleted对象。我不确定你的理由是什么,但它看起来 me 就像RunWorkerCompletedEventArgs AsyncCompletedEventArgs继承了一样不必要的步骤 - 并且因此,您只需将eRunWorkerCompletedEventArgs个对象)传递给UpdateComplete事件:

Private Sub workerDownloader_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        RaiseEvent UpdateComplete(Me, e)
End Sub

现在,这就是为什么这可能会解决您的问题(以及为什么我发布的MSDN链接相关):您当前这样做的方式,您正在访问e.Result调用AsyncCompletedEventArgs的构造函数。通过访问该属性,在首次检查e.Error之前,您正在创建一个场景,在评估要传递给UpdateComplete的参数的过程中抛出异常。由于此例外,您的RaiseEvent行无法完成其正在执行的操作;因此,您的UpdateComplete事件未被提升。

答案 1 :(得分:1)

根据您对问题的更新进行更新... 我在C#代码中嘲笑了这个问题,看起来它是一个(交叉线程?)问题,试图将Result从事件args传递给AsyncCompletedEventArgs。

传递错误和取消有效,但是当我尝试传递结果对象时,它就会死掉。您是否需要事件中的结果对象?

UpdateComplete(this, new AsyncCompletedEventArgs(e.Error, e.Cancelled, null));