是否有比忙碌等待检查System.Net.WebClient.DownloadFileAsync()下载完成更聪明的方法
本文关键字:下载 方法 更聪明 DownloadFileAsync WebClient 等待 Net System 检查 是否 | 更新日期: 2023-09-27 17:50:27
我正在使用System.Net.WebClient.DownloadFileAsync()下载文件。使用异步版本的唯一原因是显示下载的进度。在达到100%之前,我的代码执行可能无法继续。目前我正在使用一个繁忙等待(见代码),但我想知道是否有一个更聪明的方法来做到这一点。
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);
}
}
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();
}
使用AutoResetEvent。在DownloadFileCompleted事件处理程序中调用它的Set()方法,在DownloadFileAsync()调用之后调用它的WaitOne()方法。
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();
}
我已经扩展了@OJ的答案,在OpenReadCompleted
触发时设置通知器。如果文件在下载过程中出现错误,这将阻止线程挂起。
Ref: WebClient DownloadFileAsync hang