-1

I have foreach, that parses out file URL. At the end of each cycle I want to download the file, but, as I have it now, it downloads all of them. I need to figure out how to block UI thread (that has foreach in it) while download finishes.

What I have now:

foreach (... in ...)
{
  //some code that extracts FileURL and fileName
  downloadFile(FileURL, fileName)
  //should wait here, without blocking UI
  //are.WaitOne(); //this blocks the UI
}

AutoResetEvent are = new AutoResetEvent(false);
void downloadFile(String FileURL, String fileName)
{
  Thread bgThread = new Thread(() =>
  {
    WebClient FileClient = new WebClient();
    FileClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileClient_DownloadProgressChanged);
    FileClient.DownloadFileCompleted += new AsyncCompletedEventHandler(FileClient_DownloadFileCompleted);
    FileClient.DownloadFileAsync(new Uri(FileURL), fileName);
  //should wait here, without blocking UI
  //are.WaitOne(); //this either downloads one, or both in paralel.
  });
  bgThread.Start();

}

void FileClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
  this.BeginInvoke((MethodInvoker)delegate
  {
    label5.Text = String.Format("Downloaded {0} of {1} bytes...", e.BytesReceived.ToString(), e.TotalBytesToReceive.ToString());
    progressBar1.Value = e.ProgressPercentage;
  });
}

void FileClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
  this.BeginInvoke((MethodInvoker)delegate
  {
    label5.Text = "Done.";
    //stop the waiting
    are.Set();
  });
}

So, is there a way to wait for UI thrad while DownloadFileAsync finishes, and then continue with my big foreach?

1 Answers1

0

You could do something like this:

List<Task> tasks = new List<Task>();
foreach(....)
{

Thread bgThread = new Thread(() =>
  {
    WebClient FileClient = new WebClient();
    FileClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileClient_DownloadProgressChanged);
    FileClient.DownloadFileCompleted += new AsyncCompletedEventHandler(FileClient_DownloadFileCompleted);
    FileClient.DownloadFileAsync(new Uri(FileURL), fileName);
  //should wait here, without blocking UI
  //are.WaitOne(); //this either downloads one, or both in paralel.
  });
  bgThread.Start();

    tasks.Add(bgThread);


}

var arr = tasks.ToArray();
Task.WaitAll(arr);
Thiago Custodio
  • 17,332
  • 6
  • 45
  • 90
  • If I do understand this correctly, they would still run all at the same time. This project could have hundread or so files in foreach. Situation like this would bring end times to system resources. This is why I would like to have a way for files to be downloaded one at a time. – hithfaeron Mar 14 '13 at 21:06
  • No, it does not work. Thread.Join() does not work either and checking for bgThread.IsAlive does not work either. – hithfaeron Mar 16 '13 at 09:51
  • Since you are using async, it will delegate the callback and won't block your iteration inside foreach statement. – Thiago Custodio Mar 18 '13 at 02:35
  • Here: I found one old answer that maybe will help you: http://stackoverflow.com/a/6992743/1384539 – Thiago Custodio Mar 18 '13 at 02:39