DownloadFileAsync抛出未处理的异常
本文关键字:异常 未处理 DownloadFileAsync | 更新日期: 2023-09-27 18:17:58
我正在使用c#的WebClient下载文件。我使用client.DownloadFileAsnyc()。在过去这工作得很好,任何异常都会被捕获并在完成处理程序(AsyncCompletedEventArgs.Error)中返回
但现在我发现,如果我在下载期间耗尽了目标位置的空间,ioexception会被抛出并导致应用程序崩溃。有人知道为什么这不会被捕获,并在完成处理程序返回?
注意:我也试过把DownloadFileAsync行在一个尝试捕捉。仍然没有go
代码如下:
_client = new WebClient();
_client.DownloadProgressChanged += ProgressChanged;
_client.DownloadFileCompleted += DownloadComplete;
_client.DownloadFileAsync(new Uri(url), Destination);
private void DownloadComplete(object sender, AsyncCompletedEventArgs args)
{
}
系统的MSDN文档。ComponentModel表明你的DownloadFileCompleted处理程序确实应该接收到异常,但显然这里没有发生。你可以尝试在WebClient上挂一些其他*Completed事件,看看它是否被发送到那里。
在任何情况下,你都没有捕捉到异常,因为它没有发生在执行try/catch块的线程上。
当你使用async api函数(通常指任何以"async"或"Begin"结尾的函数名)时,实际操作发生在线程池中,而不是在启动操作的线程上。在try/catch中包围操作将无法捕获后台线程上的失败。
要正确捕获应用程序中的所有异常,可以安装一个全局异常处理程序,当抛出的异常在程序的其他地方未被捕获时,该异常处理程序将被调用。
一个简单的方法是使用同步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);
请注意,这个例子有点滥用了系统线程池,特别是如果您使用它来下载大文件,那么下载将花费超过一秒钟左右的时间。如果你正在下载较大的文件,或者同时下载多个文件,你绝对不应该这样做。