简体   繁体   English

WebClient.DownloadFileAsync-下载多个文件时,如何跟踪下载的字节总数?

[英]WebClient.DownloadFileAsync - How do I keep track of the total amount of bytes downloaded when downloading multiple files?

So I'm trying to download two images and just for demonstration I've checked their sizes and summed it up to a variable called totalBytes . 因此,我尝试下载两个图像,仅出于演示目的,我检查了它们的大小并将其总和成一个名为totalBytes的变量。

I want to keep track of how much has been downloaded out of those total bytes so I can calculate the percentage by taking downloaded / totalBytes * 100 我要跟踪已下载的总字节数,因此我可以通过downloaded / totalBytes * 100来计算百分比

But I have no idea how to keep track of the mount of bytes that has been downloaded. 但是我不知道如何跟踪已下载的字节数。

public static int totalBytes = 1378954;
static void Main(string[] args)
{
    var images = new List<string>
    {
        "http://4.bp.blogspot.com/-HTvSYzA-pO4/UgQb4Zh_u0I/AAAAAAAAEuI/XwhtogT_1tA/s1600/3+cute2.jpg",
        "http://getwallpapers.com/wallpaper/full/7/7/0/74728.jpg"
    };
    foreach (var image in images)
    {
        int i = 0;
        using (var wc = new WebClient())
        {
            wc.DownloadProgressChanged += Wc_DownloadProgressChanged;
            wc.DownloadFileAsync(new Uri(image), $"image{i}.png");
            i++;

            Console.ReadKey();
        }

    }
}

private static void Wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    Console.WriteLine($"Downloaded: {e.BytesReceived} out of {totalBytes}");
}

Assuming that you do not intend to actually start downloading files in parallel (as you dispose the WebClient before starting another download), the problem can be solved with two field 假设您不打算实际开始并行下载文件(因为在开始另一次下载之前处理WebClient ),可以通过两个字段来解决问题

  1. One to store the current total 一个存储当前总数
  2. Another to store the previous ReceivedByte value 另一个存储先前的ReceivedByte值

     private static long _totalBytesReceivedAllFiles = 0; private static long _previousBytesReceivedForCurrentFile = 0; private static object _lock = new Object(); private static void Wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { // There are no guarantees in the documentation that such events are serialized and can't execute in parallel even for a single file, // thus we will use lock to at least partially serialize it and ensure atomic field access. // !!!It is not intended to handle actual parallel downloads!!! lock (_lock) { _totalBytesReceivedAllFiles = _totalBytesReceivedAllFiles - _previousBytesReceivedForCurrentFile + e.BytesReceived; _previousBytesReceivedForCurrentFile = e.BytesReceived; Console.WriteLine($"Downloaded: {_totalBytesReceivedAllFiles} out of {totalBytes}"); if (e.ProgressPercentage == 100) { Console.WriteLine("Current file downloaded"); _previousBytesReceivedForCurrentFile = 0; } } } 

If on the other hand you want to start downloads truly in parallel, then you will have to 另一方面,如果您要真正开始并行下载,则必须

  1. Not to dispose (in the loop!) the client, for obvious reasons. 出于明显的原因,不要处置(循环中!)客户端。
  2. Use a per-file Wc_DownloadProgressChanged with closure to have an actual per-file _previousBytesReceivedForCurrentFile 使用带闭包的每个文件Wc_DownloadProgressChanged来获取实际的每个文件_previousBytesReceivedForCurrentFile

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM