WebClient получил больше байтов, чем TotalBytesToReceive - PullRequest
0 голосов
/ 08 октября 2018

Я запускаю Задачу в списке удаленных файлов.
Для каждого файла я using a WebClient и выполняю webClient.DownloadFileTaskAsync(...).

В WebClient DownloadProgressChangedОбработчик Я заметил, что суммирование e.BytesReceived до завершения задачи дает намного более высокий результат, чем размер, который я получаю e.TotalBytesToReceive.

Иногда сумма полученных байтов ровно вдвое большеразмер файла, иногда намного выше.

Размер, который я получаю с 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;
}

1 Ответ

0 голосов
/ 08 октября 2018

Если вы проверите пример, приведенный для свойства BytesReceived :

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 - это "сколько байт было получено с тех пор, как мы начали этоскачать ", а не" сколько байтов было получено с момента последнего вызова этого события ".

Таким образом, you не нужно накапливать счет - накопленный счет - это то, что ужедается вам.И именно поэтому вы получаете избыточные счета - если при загрузке 100 тыс. Раз возникает событие дважды, один раз на отметке 50 тыс. И еще раз на 100 тыс., Например, ваш GlobalProgress будет равен 150 тыс.

Согласны с другимикомментарии, однако, что вы должны просто использовать ProgressPercentage, чтобы получить процент.


1 Так как сообщение о downloaded x of y bytes практически бесполезно, если y является ожидаемой суммой, ноx - это просто дельта с момента последнего отображения сообщения.

...