WebClient 收到的字节数多于 TotalBytesToReceive

WebClient received more bytes than TotalBytesToReceive

我是 运行 远程文件列表中的一个任务。
在每个文件上,我 using a WebClient 并执行 webClient.DownloadFileTaskAsync(...).

WebClient 的 DownloadProgressChanged 处理程序中,我注意到总结 e.BytesReceived 直到任务完成,给出的结果比我通过 e.TotalBytesToReceive 得到的大小高得多.

有时接收到的字节总和恰好是文件大小的两倍,有时甚至更高。

我用 e.TotalBytesToReceive 得到的尺寸是正确的,与我用 ResponseHeaders["Content-Length"] 得到的尺寸相同,检查真实文件我确定尺寸是正确的。

为什么我得到这些值?是否有 header 或其他内容,我必须删除才能获得正确的下载进度?


下载文件的方法有

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;
}

如果您查看为 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);
}

请注意,它只是将值报告为 "transfer progress"。我同意这里的文档可能更详尽,因为它有点模棱两可,但对我来说(这个例子1),很明显 BytesReceived 是 "how many bytes have been received since we started this download" , 不是 "how many bytes have been received since this event was last raised".

因此,you 无需累积计数 - 累积计数就是已经提供给您的计数。这就是为什么你会多计 - 如果下载 100k 引发事件两次,一次在 50k 标记处,一次在 100k 处,例如,你的 GlobalProgress 将为 150k。

同意其他评论,但您应该只使用 ProgressPercentage 来获取百分比。


1因为如果 y 是预期总数但 x 只是增量,则说明 downloaded x of y bytes 的消息实际上没有用上次显示消息。