Is there a smarter way than waiting to check if System.Net.WebClient.DownloadFileAsync () has finished loading?

I am uploading a file using System.Net.WebClient.DownloadFileAsync (). The only reason to use the asynchronous version is to show the download progress. My code execution cannot continue until it reaches 100%. I am currently using lively waiting (see Code), but I am wondering if there is a more reasonable way to do this.

using(WebClient oWebClient = new WebClient()) { oWebClient.Encoding = System.Text.Encoding.UTF8; long lReceived = 0; long lTotal = 0; // Set up a delegate to watch download progress. oWebClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e) { Console.WriteLine(e.ProgressPercentage + "% (" + e.BytesReceived / 1024f + "kb of " + e.TotalBytesToReceive / 1024f + "kb)"); // Assign to outer variables to allow busy-wait to check. lReceived = e.BytesReceived; lTotal = e.TotalBytesToReceive; }; oWebClient.DownloadFileAsync(new Uri(sUrl + "?" + sPostData), sTempFile); while(lReceived == 0 || lReceived != lTotal) { // Busy wait. Thread.Sleep(1000); } } 
+7
source share
3 answers
 using(WebClient oWebClient = new WebClient()) { // use an event for waiting, rather than a Thread.Sleep() loop. var notifier = new AutoResetEvent(false); oWebClient.Encoding = System.Text.Encoding.UTF8; long lReceived = 0; long lTotal = 0; // Set up a delegate to watch download progress. oWebClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e) { Console.WriteLine(e.ProgressPercentage + "% (" + e.BytesReceived / 1024f + "kb of " + e.TotalBytesToReceive / 1024f + "kb)"); // Assign to outer variables to allow busy-wait to check. lReceived = e.BytesReceived; lTotal = e.TotalBytesToReceive; // Indicate that things are done if(lReceived >= lTotal) notifier.Set(); }; oWebClient.DownloadFileAsync(new Uri(sUrl + "?" + sPostData), sTempFile); // wait for signal to proceed notifier.WaitOne(); } 
+8
source

Use AutoResetEvent. Call its Set () method in the DownloadFileCompleted event handler, its WaitOne () method after calling DownloadFileAsync ().

+5
source
 using(WebClient oWebClient = new WebClient()) { // use an event for waiting, rather than a Thread.Sleep() loop. var notifier = new AutoResetEvent(false); oWebClient.Encoding = System.Text.Encoding.UTF8; long lReceived = 0; long lTotal = 0; // Set up a delegate to watch download progress. oWebClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e) { Console.WriteLine(e.ProgressPercentage + "% (" + e.BytesReceived / 1024f + "kb of " + e.TotalBytesToReceive / 1024f + "kb)"); // Assign to outer variables to allow busy-wait to check. lReceived = e.BytesReceived; lTotal = e.TotalBytesToReceive; }; // Set a delegate to watch for when the download is complete oWebClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e) { // Indicate that things are done notifier.Set(); }; oWebClient.DownloadFileAsync(new Uri(sUrl + "?" + sPostData), sTempFile); // wait for signal to proceed notifier.WaitOne(); } 

I extended @OJ's answer instead to set a notifier when OpenReadCompleted . This will stop the thread from freezing if file errors occur during download.

Link: WebClient DownloadFileAsync hanging

0
source