2010-06-01 75 views
0

我熟悉以下內容:的BackgroundWorker RunWorkerCompleted在組件

「如果操作引發你的代碼不處理異常,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)) 

我需要的組件暴露工人通過公共事件例外。

如果我刪除了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

您能提供一個完整的代碼示例嗎?我不清楚「RunWorkerComplete」是什麼。 – 2010-06-01 16:55:39

+0

剛發佈。謝謝史蒂夫 – SharpAffair 2010-06-01 17:22:47

+0

我已經更新了我的答案,更詳細地解釋了爲什麼我相信你會遇到這個問題。看看,讓我知道它是否有幫助。 – 2010-06-01 18:09:44

回答

1

根據您對問題的更新進行更新... 我在C#代碼中嘲笑了這一點,它看起來像是(跨線程?)問題,嘗試將事件參數的結果傳遞給AsyncCompletedEventArgs。

傳遞錯誤和取消工作,但是當我嘗試傳遞結果對象時,它就會死亡。你在事件中需要結果對象嗎?

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

這次我不需要一個結果,而且工作,謝謝。但是反正有點怪,不是嗎? – SharpAffair 2010-06-01 19:02:19

2

這可能是因爲你的e.Result拋出自己的異常。

the MSDN documentation on RunWorkerCompletedEventArgs

RunWorkerCompleted事件 處理程序應該始終訪問Result 屬性之前檢查 ErrorCancelled性能 。如果發生異常 或操作被取消, 訪問Result屬性引發 例外。

具體來說,它會提高TargetInvocationException

在您發佈的代碼中,您正在通過RunWorkerCompleted事件傳遞的參數構造一個新的AsyncCompletedEventArgs對象。我不知道你的這個理由是什麼,但它看起來是不必要的步驟,因爲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事件沒有被提出。

+0

情況並非如此,因爲未處理的異常是我拋出的異常(ArgumentException - 「Test」)。 我使用「如果e.Error IsNot Nothing Then MessageBox.Show(e.Error.ToString)」 任何其他建議? – SharpAffair 2010-06-01 16:57:06

+0

@Sphynx,當你創建一個'AsyncCompletedEventArgs'時,你正在訪問'e.Result'而不檢查是否有錯誤或者工作者是否被取消。 – 2010-06-01 17:29:48

相關問題