在使用C#的BackgroundWorker時需要在UI界面上顯示DoWork中發生的異常,但怎么調試都無法跳轉到界面上,異常也不會傳遞到RunWorkerCompleted方法中(e.Error為空)。在網上搜了很多類似的問題都沒有找到答案(搜索方法不對,還是運氣不好?),幸好在CSDN上搜到了一個相似的問題(如何統一處理BackgroundWork產生的異常),看到里面說使用“開始執行(不調試)”依然無法傳遞出異常,才想到可能是調試的問題,改用“開始執行(不調試)”(調試菜單,或CTRL+F5)成功解決這個問題。眼睛疼,睡覺。
DoWork方法執行時發生異常並中斷程序運行,無法通過e.Error獲取異常:
界面上顯示錯誤:
補充:上述的解決方法在正式執行使用程序時還是發生了問題,沒有將異常傳遞到Completed函數中。后來使用了一個稍微麻煩點的方法處理:在DoWork中使用try-catch對異常進行捕獲,而不通過系統自動拋出(如上面所說,如果自己不進行捕獲,調試時異常無法進入Completed函數處理),然后將捕獲的異常賦值給e.Result返回給Completed函數進行處理,這樣可以在調試模式下跟蹤異常。為了便於使用,我自定義了一個額外的類WorkResult來表示DoWork返回的結果,其中包括一個Exception類型的屬性Error用於保存捕獲的異常和一個string類型(也可以是object類型)的屬性Result用於保存DoWork需要返回的結果,最后在DoWork結束時將這個WorkResult的實例賦值給e.Result,這樣就可以在RunWorkerCompleted函數中通過e.Result獲取DoWork的操作結果和異常。部分代碼如下。
定義WorkResult類並在DoWork函數中將異常和操作結果存入WorkResult實例中:
class WorkResult { public OperationType Operation { get; set; } public Exception Error { get; set; } public string Result { get; set; } }
private void DoWork(object sender, DoWorkEventArgs e) { WorkResult result = new WorkResult();//自定義返回結果,包括操作類型和WebService執行的結果 Exception ex = null; //DoWork需要處理的工作 .......... if (ex != null) { result.Error = ex; } e.Result = result; }
在RunWorkerCompleted函數中處理異常(通知用戶發生錯誤或者其他操作):
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //取得DoWork操作結果 WorkResult result = e.Result as WorkResult; if (result == null) { MessageBox.Show("發生錯誤!異步操作返回結果不是WorkResult類型。"); return; } if (result.Error != null) { //如果異步操作過程中發生異常,那么在這里處理 ...... } else { //對結果進行處理 ...... } }
如果大家對於這個問題有其他的解決方法還請在評論區貼出來,以便於遇到這個問題但不知道怎么解決的朋友使用,謝謝。