我正在使用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下编译的。
发布于 2013-06-12 22:47:05
MSDN docs for System.ComponentModel表明您的DownloadFileCompleted处理程序确实应该接收异常,但显然这里没有发生这种情况。您可以尝试挂接WebClient上的其他一些*Completed事件,以查看是否正在将其发送到那里。
在任何情况下,您都不会捕获异常,因为它不会发生在执行try / catch块的线程上。
当您使用异步api函数(通常指任何以" async“或”Begin“结尾的函数名)时,实际操作发生在线程池中,而不是在启动操作的线程上。将操作包围在try/catch中不会捕获后台线程上的故障。
要正确捕获应用程序中的所有异常,您可以安装一个global exception handler,只要抛出一个在程序中其他地方没有捕获到的异常,就会调用该all。
绕过此行为的一种简单方法是使用同步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);请注意,这个示例有点滥用系统线程池,特别是当您使用它下载大文件时,下载时间超过一秒左右。如果你正在下载更大的文件,或者同时下载很多文件,你绝对不应该这样做。
https://stackoverflow.com/questions/17067915
复制相似问题