【问题标题】:DownloadFileAsync throwing unhandled exceptions?DownloadFileAsync 抛出未处理的异常?
【发布时间】:2013-06-08 16:59:34
【问题描述】:

我在 C# 中使用 WebClient 来下载文件。我正在使用 client.DownloadFileAsnyc()。在过去这很好用,任何异常都会被捕获并在完成处理程序中返回 (AsyncCompletedEventArgs.Error)

但是现在我发现如果在下载过程中目标位置的空间不足,IOExcption 就会被抛出并导致应用程序崩溃。有谁知道为什么这不会在完成处理程序中被捕获并返回?
注意:我还尝试将 DownloadFileAsync 行放在 try catch 中。还是不行

代码如下:

_client = new WebClient();
_client.DownloadProgressChanged += ProgressChanged;
_client.DownloadFileCompleted += DownloadComplete;
_client.DownloadFileAsync(new Uri(url), Destination);

private void DownloadComplete(object sender, AsyncCompletedEventArgs args)
{
}

这是在 .NET 3.5 下编译的。

【问题讨论】:

  • 哪里抛出异常?
  • 调用堆栈只是说“[外部代码]”,我看不到其他细节:\

标签: c# .net exception download webclient


【解决方案1】:

MSDN docs for System.ComponentModel 表明您的 DownloadFileCompleted 处理程序确实应该收到异常,但显然这里没有发生这种情况。您可以尝试在 WebClient 上挂钩其他一些 *Completed 事件,以查看它是否被发送到那里。

在任何情况下,您都没有捕获异常,因为它没有发生在执行 try / catch 块的线程上。

当您使用 async api 函数(通常表示任何以“Async”或“Begin”结尾的函数名称)时,实际操作发生在线程池中,而不是在您启动操作的线程上。将操作包围在 try/catch 中不会捕获后台线程上的故障。

要正确捕获应用程序中的所有异常,您可以安装一个global exception handler,只要在您的程序中的其他地方没有捕获到异常,就会调用它。

解决此问题的一种简单方法是使用同步 client.DownloadFile() 函数,然后从后台线程调用该函数,这样您就不会阻塞程序的主线程。下面是一个简单粗暴的例子来演示它:

// create a thread function to download a file synchronously
function DoDownload(object state){
    List<String> st = (List<String>)(state);
    String uri = st[0];
    String fname = st[1];
    try {
        client.DownloadFile(uri, fname);
    } catch {
        // you'll catch the exception here because the 
        // try/catch is on the same thread that is doing the downloading
    }
}

//  somewhere else, when you want to actually start the download:
String uri = "http://example.com/the_file.txt";
string theFileName = "destination.txt";
List<String> st = new List<String>{ theUri, theFileName };
ThreadPool.QueueUserWorkItem(DoDownload, st);

请注意,这个例子有点滥用系统线程池,特别是如果你将它用于下载需要超过一秒左右的大文件。如果您正在下载较大的文件,或者同时下载许多文件,则绝对不应该这样做。

【讨论】:

    猜你喜欢
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多