WebClient.DownloadFileAsync - Download files one at a time
asp.net, c#, download, multithreading, webclient
Solution
To simplify the task you can create separated attachment list:
list = new List<Attachment>(wi.Attachments);
where list is private field with type List<Attachment>. After this you should configure WebClient and start downloading of first file:
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:
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.
Problem
I am using the code below to download multiple attachments from a TFS server: ``` 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. One may ask "Why don't you just use the synchronous DownloadFile method?" Its because: - 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. 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 ALL files has been downloaded. I don't know if this is a side-effect of using System.Threading.Thread.Sleep(1000); Is there a better approach to download files one at a time using WebClient.DownloadFileAsync? Thanks!