我正在远程文件列表上运行任务。
在每个文件上,我都是using
和WebClient
,并执行webClient.DownloadFileTaskAsync(...)
。
在WebClient
的DownloadProgressChanged处理程序中,我注意到对e.BytesReceived
进行总计直到任务完成为止,得出的结果要比e.TotalBytesToReceive
得到的结果高得多。 / p>
有时接收到的字节之和恰好是文件大小的两倍,有时甚至更高。
我用e.TotalBytesToReceive
得到的大小是正确的,与我用ResponseHeaders["Content-Length"]
得到的大小是相同的,并检查真实文件,我确定大小正确。
为什么我得到这些值?为了获得正确的下载进度,是否必须删除标题或其他内容?
下载文件的方法是
private async Task DownloadFiles(List<FileDetails> files)
{
await Task.WhenAll(files.Select(p => DownloadFileAsync(p)));
}
和
private async Task DownloadFileAsync(FileDetails f)
{
string localPath = @"C:\myDir";
try
{
using (WebClient webClient = new WebClient())
{
webClient.DownloadProgressChanged += MyHandler;
webClient.Credentials = CredentialCache.DefaultNetworkCredentials;
await webClient.DownloadFileTaskAsync(f.Path, localPath);
}
}
catch ()
{
}
}
处理进度的代码:
void MyHandler(object sender, DownloadProgressChangedEventArgs e)
{
//GlobalProgress and GlobalPercentage are global variables
//initialized at zero before the download task starts.
GlobalProgress += e.BytesReceived;
//UpdateDownloadTotal is the sum of the sizes of the
//files I have to download
GlobalPercentage = GlobalProgress * 100 / UpdateDownloadTotal;
}
答案 0 :(得分:1)
如果您查看为BytesReceived
property给出的示例:
private static void DownloadProgressCallback(object sender, DownloadProgressChangedEventArgs e) { // Displays the operation identifier, and the transfer progress. Console.WriteLine("{0} downloaded {1} of {2} bytes. {3} % complete...", (string)e.UserState, e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage); }
请注意,它仅以“转移进度”报告该值。我同意这里的文档可能会更详尽,因为它有点模棱两可,但是对我来说(使用本示例 1 ),很明显BytesReceived
是“自从我们开始了此下载”,而不是“自上次引发此事件以来已收到多少字节”。
因此,您不需要累积计数-累积计数就是已经提供给您的计数。这就是为什么您超支的原因-例如,如果下载量为100k,则两次引发该事件,一次为50k,一次为100k,那么您的GlobalProgress
将为150k。
同意其他评论,尽管您只应使用ProgressPercentage
来获取百分比。
1 因为如果声明downloaded x of y bytes
是期望的总数,但是声明y
的消息实际上是无用的,而x
只是自上次显示消息以来的增量。