Reputation: 36111
I need to download several HTML files in my ASP.NET application. The average file size is about 100 KB.
Right now I'm using the following code.
foreach (var item in items)
{
string url = (string)item.Element("link");
string title = (string)item.Element("title");
string fileName = Server.MapPath(title + ".html");
// Add the attachement
WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
client.DownloadFileCompleted += new AsyncCompletedEventHandler((a, b) =>
{
System.Threading.Thread.Sleep(2000);
message.Attachments.Add(new Attachment(fileName));
counter++;
// If we've downloaded all the items, send the message with the items attached to it
if (counter == totalItems)
{
SendMessage(message);
}
});
client.DownloadFileAsync(new Uri(url), fileName);
}
As you can see I'm downloading the files asynchronously, but the foreach loop doesn't care that the file hasn't been downloaded yet, it goes to the next iterated item.
As a result of this, some of the files are not downloaded.
Upvotes: 0
Views: 172
Reputation: 12561
It could as simple as a bug in your code to populate totalItems
.
Try if (counter == items.Count())
instead of
if (counter == totalItems)
Upvotes: 0
Reputation: 217293
Use the CountdownEvent Class to count down the number of remaining files.
var cde = new CountdownEvent(items.Count);
foreach (var item in items)
{
...
client.DownloadFileCompleted += (a, b) =>
{
lock (message)
{
message.Attachments.Add(new Attachment(fileName));
cde.AddCount();
}
};
...
}
// If we've downloaded all the items,
// send the message with the items attached to it
cde.Wait();
lock (message)
{
SendMessage(message);
}
Upvotes: 3
Reputation: 56162
If you're using .NET Framework 4 you could use Task class and WaitAll
method.
Upvotes: 2