Is there a smarter way than a busy-wait to check for download completion of System.Net.WebClient.DownloadFileAsync()?

前端 未结 3 1536
长情又很酷
长情又很酷 2021-01-05 08:47

I\'m downloading a file using System.Net.WebClient.DownloadFileAsync(). The only reason for using the async version is to show the progress of the download. My code executio

相关标签:
3条回答
  • 2021-01-05 09:05

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

    0 讨论(0)
  • 2021-01-05 09:06
    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 have expanded on @OJ's answer to instead set the notifier when the OpenReadCompleted fires. This will stop the thread from hanging if the file errors during download.

    Ref: WebClient DownloadFileAsync hangs

    0 讨论(0)
  • 2021-01-05 09:19
    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();
    }
    
    0 讨论(0)
提交回复
热议问题