C# WebClient.DownloadFileAsync - 一次下载一个文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2042258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WebClient.DownloadFileAsync - Download files one at a time
提问by Ian
I am using the code below to download multiple attachments from a TFS server:
我正在使用下面的代码从 TFS 服务器下载多个附件:
foreach (Attachment a in wi.Attachments)
{
WebClient wc = new WebClient();
wc.Credentials = (ICredentials)netCred;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(a.Uri, "C:\" + a.Name);
}
I would like to download multiple files using DownloadFileAsync, but I want them to be downloaded one by one.
我想使用 DownloadFileAsync 下载多个文件,但我希望它们被一个一个地下载。
One may ask "Why don't you just use the synchronous DownloadFile method?" Its because:
有人可能会问“为什么不直接使用同步 DownloadFile 方法?” 这是因为:
- I want to make use of the events provided by DownloadFileAsync.
- I don't want to make multiple instances of the Webclient to avoid flooding the server.
- 我想利用 DownloadFileAsync 提供的事件。
- 我不想创建多个 Webclient 实例以避免淹没服务器。
This is the solution that I thought of:
这是我想到的解决方案:
foreach (Attachment a in wi.Attachments)
{
WebClient wc = new WebClient();
wc.Credentials = (ICredentials)netCred;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(a.Uri, "C:\" + a.Name);
while (wc.IsBusy)
{
System.Threading.Thread.Sleep(1000);
}
}
However, there are a couple of problems with this approach:
但是,这种方法有几个问题:
- The Thread.Sleep() is locking up my Form. I still need to make my own Thread or use BackgroundWorker. (I would like to avoid this as much as possible)
- The DownloadFileCompleted event is being triggered after ALLfiles has been downloaded. I don't know if this is a side-effect of using System.Threading.Thread.Sleep(1000);
- Thread.Sleep() 正在锁定我的表单。我仍然需要创建自己的线程或使用BackgroundWorker。(我想尽可能避免这种情况)
- 下载所有文件后触发 DownloadFileCompleted 事件。我不知道这是否是使用 System.Threading.Thread.Sleep(1000) 的副作用;
Is there a better approach to download files one at a time using WebClient.DownloadFileAsync?
是否有更好的方法使用 WebClient.DownloadFileAsync 一次下载一个文件?
Thanks!
谢谢!
采纳答案by Andrey Shvydky
To simplify the task you can create separated attachment list:
为了简化任务,您可以创建单独的附件列表:
list = new List<Attachment>(wi.Attachments);
where listis private field with type List<Attachment>. After this you should configure WebClient and start downloading of first file:
其中list是类型为List<Attachment> 的私有字段。在此之后,您应该配置 WebClient 并开始下载第一个文件:
if (list.Count > 0) {
WebClient wc = new WebClient();
wc.Credentials = (ICredentials)netCred;
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(list[0].Uri, @"C:\" + list[0].Name);
}
Your DownloadFileComplete handler should check if not all files already downloaded and call DownloadFileAsync again:
您的 DownloadFileComplete 处理程序应检查是否所有文件都已下载并再次调用 DownloadFileAsync:
void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) {
// ... do something useful
list.RemoveAt(0);
if (list.Count > 0)
wc.DownloadFileAsync(list[0].Uri, @"C:\" + list[0].Name);
}
This code is not optimized solution. This is just idea.
此代码不是优化的解决方案。这只是想法。
回答by heavenwing
I think that should use Queue
我认为应该使用 Queue
回答by user2667898
At the risk of sounding like an idiot, this worked for me:
冒着听起来像个白痴的风险,这对我有用:
Console.WriteLine("Downloading...");
client.DownloadFileAsync(new Uri(file.Value), filePath);
while (client.IsBusy)
{
// run some stuff like checking download progress etc
}
Console.WriteLine("Done. {0}", filePath);
Where client
is an instance of a WebClient
object.
对象client
的实例在哪里WebClient
。