System.ComponentModel的MSDN 文档表明您的 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);
请注意,这个例子有点滥用系统线程池,特别是如果你将它用于下载需要超过一秒左右的大文件。如果您正在下载较大的文件,或者同时下载许多文件,则绝对不应该这样做。