2011-03-02 33 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