我有数千个下载URL列表。网址可能包含其他类型的文件,例如图像,pdf,音频,视频等。我正在尝试使用DownloadFileTaskAsync下载它们。但是在下载了多个文件后,该应用程序崩溃了。我不明白发生了什么。没有收到任何错误消息。下载少量文件后,仅我的应用程序关闭。
foreach (var url in urls)
{
//if file exists in our local directory then do not need to download and continue the process...
if (FileExistsOrNot(localPath + "/" + url.fileName))
continue;
Thread thread = new Thread(async () => {
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
await client.DownloadFileTaskAsync(new Uri(url.downloadUrl), localPath + "/" + url.fileName);
});
thread.Start();
}
答案 0 :(得分:1)
每次下载都会产生一个新线程,这也就怪不得您很快耗尽了系统资源(在这种情况下为线程)。
您应该使用某种线程池,幸运的是,C#有多种现成的解决方案可以做到这一点:
ThreadPool是最低级别的构造,并行编程和任务调度程序是在此之上构建的。
当您使用异步操作下载( DownloadFileTaskAsync )时,在这种情况下,任务是最合适的选项:
Action<string, DownloadProgressChangedEventArgs> onDownloadProgress = (url, e) =>
{
/* your logic displaying progress... */
};
var downloadTasks = urls
.Where(url => !FileExistsOrNot(Path.Combine(localPath, url.fileName)))
.Select(async url =>
{
using (var client = new WebClient())
{
client.DownloadProgressChanged += (s, e) => onDownloadProgress(url.fileName, e);
try { await client.DownloadFileTaskAsync(new Uri(url.downloadUrl), Path.Combine(localPath, url.fileName)); }
catch (Exception ex) { /* handle download error: log exception, etc */ }
}
});
Task.WaitAll(downloadTasks.ToArray()); // or Task.WhenAll(...) if you want it non-blocking
一些评论: