I am trying to download multiple files from the internet and await for all of them to finish. This is a C# console application that I am running, so no progress bar event handler should be necessary. However it currently just continues to execute code even though all files have not been downloaded.
How would you await till all async download files are finished.
private void DownloadMultipleFiles(List<DocumentObject> doclist)
{
foreach(var value in doclist){
try
{
using (WebClient webClient = new WebClient())
{
string downloadToDirectory = @Resources.defaultDirectory + value.docName;
webClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
webClient.DownloadFileCompleted += client_DownloadFileCompleted;
webClient.DownloadFileAsync(new Uri(value.docUrl), @downloadToDirectory);
//Add them to the local
Context.listOfLocalDirectories.Add(downloadToDirectory);
}
}
catch (Exception)
{
Errors.printError("Failed to download File: " + value.docName);
}
}
}
The DownloadFileAsync
/DownloadFileCompleted
members of WebClient
use the Event-based Asynchronous Pattern. If you want to use async
and await
, you should be using the Task-based Asynchronous Pattern.
In this case, you should use the DownloadFileTaskAsync
member, as such:
private async Task DownloadFileAsync(DocumentObject doc)
{
try
{
using (WebClient webClient = new WebClient())
{
string downloadToDirectory = @Resources.defaultDirectory + doc.docName;
webClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
await webClient.DownloadFileTaskAsync(new Uri(doc.docUrl), @downloadToDirectory);
//Add them to the local
Context.listOfLocalDirectories.Add(downloadToDirectory);
}
}
catch (Exception)
{
Errors.printError("Failed to download File: " + doc.docName);
}
}
private async Task DownloadMultipleFilesAsync(List<DocumentObject> doclist)
{
await Task.WhenAll(doclist.Select(doc => DownloadFileAsync(doc)));
}
Please note that your Context.listOfLocalDirectories.Add
and Errors.printError
methods should be threadsafe.