使用异步编程捕获异常

时间:2011-03-02 06:41:47

标签: c# asynchronous

VS C#2005

我使用下面的代码使用Web客户端上传文件Async。但是,如果出现问题,我不确定是否可以捕获异常。因为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冻结。

非常感谢任何建议,

2 个答案:

答案 0 :(得分: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 :(得分:4)

由于调用是异步的,因此您的线程将继续执行并退出try..catch块,因此不会发生异常。相反,您应该检查Error事件处理程序中eventargs对象的UploadFileCompleted属性。如果进程中存在异常,则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
    }
}

这是异步编程中的常用方法;异步方法捕获异常并将其存储在异步调用完成后可以检查异常的地方。