[英]DownloadFileTaskAsync does not work to download thousands of file
I have a thousands list of download url.我有数千个下载网址列表。 The url may contain a different type of file such as that image, pdf, audio, video etc. I am trying to download them using DownloadFileTaskAsync.该 url 可能包含不同类型的文件,例如该图像、pdf、音频、视频等。我正在尝试使用 DownloadFileTaskAsync 下载它们。 But after several files downloading the app is breaking down.但是在下载了几个文件后,该应用程序崩溃了。 I don't understand what is happening.我不明白发生了什么。 don't get any error message.不要收到任何错误信息。 Just my app is shut down after few files downloading.只是我的应用程序在下载几个文件后关闭。
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();
}
Spawning a new thread for every download it's no wonder that you quickly run out of system resources (threads in this case).为每次下载生成一个新线程,难怪您会很快耗尽系统资源(在本例中为线程)。
You should use some kind of thread pooling and luckily, C# has multiple out-of-the-box solution to do this:您应该使用某种线程池,幸运的是,C# 有多种开箱即用的解决方案来执行此操作:
ThreadPool is the lowest level construct, parallel programming and task schedulers are built on top of that. ThreadPool 是最低级别的构造,并行编程和任务调度程序构建在此之上。
As you use an async operation to download ( DownloadFileTaskAsync ), tasks are the most suitable option in this case:当您使用异步操作下载 ( 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
Some remarks:一些备注:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.