2011-03-02 39 views
2

VS C#2005使用異步編程捕捉異議

我正在使用下面的代碼上傳文件異步使用Web客戶端。但是,如果出現問題,我不確定是否可以發現異常情況。因爲wc.UpLoadFileAsync會立即返回。所以把try...catch放在那裏似乎毫無意義。

因此,爲了測試,我特意創建了一個錯誤,以查看如果我輸入錯誤的URL會發生什麼情況。但是,我在我的調試輸出窗口中得到了這個。

A first chance exception of type 'System.Net.WebException' occurred in System.dll 
File completed 

所以它不會在try...catch發生火災。它仍是起火的UploadFileCompleted方法

private void upload_config_to_server() 
{ 
    Uri url = new Uri("http://10.10.10.3/softphone/config.xml"); 

    WebClient wc = new WebClient(); 
    if (!wc.IsBusy) 
    { 
     wc.UploadProgressChanged += new UploadProgressChangedEventHandler(wc_UploadProgressChanged); 
     wc.UploadFileCompleted += new UploadFileCompletedEventHandler(wc_UploadFileCompleted);  

     try 
     { 
      wc.UploadFileAsync(url, "PUT", "config.xml"); 
     } 
     catch (WebException webex) 
     { 
      Console.WriteLine("Web Exception {0}", webex.Message); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Exception {0}", ex.Message); 
     } 
    } 
} 

private void wc_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e) 
{ 
    Console.WriteLine("Bytes uploaded {0}", e.BytesSent); 
} 

private void wc_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e) 
{ 
    Console.WriteLine("File completed"); 
} 

是否有處理這個正確的方式。我只想向用戶顯示一個消息框,以顯示上傳文件失敗的原因。但是,由於上傳的文件可能很大,上傳它可能需要幾秒鐘。所以我需要有Async來防止UI凍結。

非常感謝任何建議,

回答

4

由於調用是異步的,你的線程將繼續執行,並退出try..catch塊,所以異常不會發生在那裏。相反,您應該檢查UploadFileCompleted事件處理程序中eventargs對象的Error屬性。如果在此過程中有異常,Error屬性將包含異常對象。另外,我認爲將事件處理程序分開是個好主意:

static void wc_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e) 
{ 
    wc.UploadProgressChanged -= wc_UploadProgressChanged; 
    wc.UploadFileCompleted -= wc_UploadFileCompleted; 

    if (e.Error != null) 
    { 
     // there was an error 
    } 
} 

這是異步編程中的常用方法;異步方法捕獲異常並將其存儲在可以在異步調用完成後檢查它的地方。

+0

這看起來不像'分離事件處理程序'。 – 2011-03-02 07:47:42

+0

@Hans:不,完全相反! :o)感謝您發現錯字,並予以更正。 – 2011-03-02 08:21:48

5

您可以檢查e.Error值。

private void wc_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    { 
     if (e.Error is WebException) 
      Console.WriteLine("Web Exception {0}", ((WebException)e.Error).Message); 
     else 
      Console.WriteLine("Web Exception {0}", e.Error.Message); 
    } 
    else if (e.Cancelled) 
     Console.WriteLine("File cancelled"); 
    else 
     Console.WriteLine("File completed"); 
} 
+1

而不是使用'is'語句。您可以使用'as'語句來鍵入強制轉換。例如,WebException webException; (WebException = e.Error as WebException)!= null) {\t Console.WriteLine(「Web Exception {0}」,webExeption.Message);}'。這將避免必須施加兩次「e.Error」。 – 2011-03-02 07:39:45

+0

@ devendra-d-chavan,是的,我同意你的意見。這是一個有效的選擇。 – 2011-03-02 07:50:40