我熟悉以下内容:
“如果操作引发了代码无法处理的异常,则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
答案 0 :(得分:2)
可能是你的e.Result
正在抛出自己的异常。
来自the MSDN documentation on RunWorkerCompletedEventArgs
:
您的
RunWorkerCompleted
活动 处理程序应该经常检查Error
和Cancelled
属性 在访问Result
之前 属性。如果引发异常 或者如果操作被取消, 访问Result
属性引发 例外。
具体来说,它会引发TargetInvocationException
。
在您发布的代码中,您正在通过AsyncCompletedEventArgs
事件传递的参数构建新的RunWorkerCompleted
对象。我不确定你的理由是什么,但它看起来 me 就像RunWorkerCompletedEventArgs
从AsyncCompletedEventArgs
继承了一样不必要的步骤 - 并且因此,您只需将e
(RunWorkerCompletedEventArgs
个对象)传递给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));