有一项任务是从带有进度显示(总和当前文件大小)的 Web 服务器下载约 3000 个文件。也就是为了方便用户,需要实现文件的总大小和总共下载多少(例如:100mb out of 300mb download)。
我从服务器以 JSON 数据的形式获取上传文件的总大小(它提供了一个列表,其中包含有关每个文件、其大小、名称等的信息),但当前大小存在困难......
我使用WebClinet
,我从中捕获事件DownloadProgressChanged
。在这个事件里面,我们可以得到BytesReceived
,也就是我们已经从这个文件下载了多少的大小,它一直在增长,直到它变成 = 文件的完整大小。
我的任务是计算在一次事件调用中下载了多少字节DownloadProgressChanged
,而不是总数。我试图将前一个保存在一个BytesReceived
单独的变量中( 11561291193(也就是差不多一半,但是所有文件都接收成功!计数不正确...)。oldSize
var size = e.BytesReceived - oldSize;
请帮助我实现从服务器下载的字节的有效输出......
当前实施:
private void RepairClient()
{
var filesBlock = new BufferBlock<FileViewModel>();
var generateOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 4,
BoundedCapacity = 100
};
var downloadBlock = new ActionBlock<FileViewModel>(async file =>
{
SetFileName(file.Name);
var packPach = file.Name + ServerData.PackName;
var uri = new Uri(main.UpdaterViewModel.Path, packPach);
var fullPackPach = Model.StorageModel.ExpandRelativeName(packPach);
await file.DownloadFile(uri, fullPackPach, main);
}, generateOptions);
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
filesBlock.LinkTo(downloadBlock, linkOptions);
var totalSize = UpdateFiles.Sum(x => x.FileSize);
SetMinMax(0, UpdateFiles.Count);
SetSize(total: totalSize); //Вывести в интерфейс полный размер.
SetMinMax(0, totalSize); //Работа с ProgressBar (задать min и max).
SetStatus(true);
UpdateFiles.ForEach(x => filesBlock.Post(x));
filesBlock.Complete();
downloadBlock.Completion.Wait();
}
我尝试使用简单的方法编写方法acync
,现在我正在玩Dataflow
,但无济于事。在 blockdownloadBlock
中,我们做通常的准备(我们计算路径)并调用DownloadFile
当前文件的方法。
方法DownloadFile
:
public async Task DownloadFile(Uri uri, string path, MainViewModel main)
{
try
{
using (var client = new WebClient())
{
long prev = 0;
client.DownloadProgressChanged += (sender, args) =>
{
var diff = args.BytesReceived - prev;
main.Progress.Size += diff;
prev = args.BytesReceived;
Console.WriteLine($"[{path}]: BytesReceived: {args.BytesReceived} (diff: {diff})");
};
var dir = Path.GetDirectoryName(path);
if (dir != null && !Directory.Exists(dir)) Directory.CreateDirectory(dir);
await client.DownloadFileTaskAsync(uri, path);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
这是结果的输出:
[patchw32.dll.client]: BytesReceived: 10215 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 3370 (diff: -2738)
[patchw32.dll.client]: BytesReceived: 11584 (diff: 9583)
[patchw32.dll.client]: BytesReceived: 2001 (diff: 2001)
[patchw32.dll.client]: BytesReceived: 6108 (diff: 6108)
[patchw32.dll.client]: BytesReceived: 8846 (diff: 8846)
[patchw32.dll.client]: BytesReceived: 4739 (diff: -6845)
[patchw32.dll.client]: BytesReceived: 12953 (diff: 8214)
[patchw32.dll.client]: BytesReceived: 7477 (diff: -5476)
[patchw32.dll.client]: BytesReceived: 14322 (diff: 6845)
[patchw32.dll.client]: BytesReceived: 15691 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 17060 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 18429 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 19798 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 21167 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 22536 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 23905 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 25274 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 26643 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 28012 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 29381 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 30750 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 32031 (diff: 1281)
[patchw32.dll.client]: BytesReceived: 33400 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 34769 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 36138 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 37507 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 38876 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 40245 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 41614 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 42983 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 44352 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 45721 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 47090 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 48459 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 49828 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 51197 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 52566 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 53935 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 55304 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 59533 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 63762 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 64799 (diff: 1037)
[patchw32.dll.client]: BytesReceived: 69028 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 73257 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 77486 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 81715 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 85944 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 90173 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 94402 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 95819 (diff: 1417)
[patchw32.dll.client]: BytesReceived: 95819 (diff: 0)
[L2text\help_battle_shot.htm.client]: BytesReceived: 1067 (diff: 1067)
[L2text\help_battle_shot.htm.client]: BytesReceived: 1067 (diff: 1067)
[L2text\help_item_symbol.htm.client]: BytesReceived: 936 (diff: 936)
[L2text\help_item_symbol.htm.client]: BytesReceived: 936 (diff: 936)
[L2text\help_option_video.htm.client]: BytesReceived: 2337 (diff: 2337)
[L2text\help_option_video.htm.client]: BytesReceived: 2337 (diff: 2337)
[L2text\credit_us_03.htm.client]: BytesReceived: 907 (diff: 907)
[L2text\credit_us_03.htm.client]: BytesReceived: 907 (diff: 907)
[L2text\pet_help_quest_2.htm.client]: BytesReceived: 809 (diff: 809)
[L2text\pet_help_quest_2.htm.client]: BytesReceived: 809 (diff: 809)
[music\S09_F.ogg.client]: BytesReceived: 1992 (diff: 1992)
[music\S09_F.ogg.client]: BytesReceived: 3361 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 4730 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 6099 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 10206 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 11575 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 7468 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 8837 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 14313 (diff: 2738)
[music\S09_F.ogg.client]: BytesReceived: 12944 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 15682 (diff: 2738)
[music\S09_F.ogg.client]: BytesReceived: 17051 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 18420 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 19789 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 21158 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 22527 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 23896 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 25265 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 26634 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 28003 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 29372 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 30741 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 31384 (diff: 643)
[music\S09_F.ogg.client]: BytesReceived: 32753 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 34122 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 35491 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 36860 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 38229 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 39598 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 40967 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 42336 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 43705 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 45074 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 46443 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 47812 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 49181 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 53410 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 57639 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 61868 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 64152 (diff: 2284)
[music\S09_F.ogg.client]: BytesReceived: 68381 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 72610 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 76839 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 81068 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 85297 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 89526 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 93755 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 96920 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 101149 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 105378 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 109607 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 113836 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 118065 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 122294 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 126523 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 129688 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 133917 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 138146 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 142375 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 146604 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 150833 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 155062 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 159291 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 162456 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 166685 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 170914 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 175143 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 179372 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 183601 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 187830 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 192059 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 195224 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 199453 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 203682 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 207911 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 212140 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 227992 (diff: 15852)
[music\S09_F.ogg.client]: BytesReceived: 244376 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 260760 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 277144 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 293528 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 309912 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 326296 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 342680 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 359064 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 375448 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 3483 (diff: 3483)
[music\sc08_f.ogg.client]: BytesReceived: 7712 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 11941 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 16170 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 20399 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 24628 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 28857 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 31383 (diff: 2526)
[music\S09_F.ogg.client]: BytesReceived: 391832 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 35612 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 39841 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 44070 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 48299 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 408216 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 52528 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 56757 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 60986 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 64151 (diff: 3165)
[music\sc08_f.ogg.client]: BytesReceived: 68380 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 72609 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 76838 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 81067 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 424600 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 440984 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 85296 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 89525 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 93754 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 96919 (diff: 3165)
[music\sc08_f.ogg.client]: BytesReceived: 101148 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 105377 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 457368 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 473752 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 121761 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 129687 (diff: 7926)
[music\S09_F.ogg.client]: BytesReceived: 490136 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 146071 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 501222 (diff: 11086)
[music\S09_F.ogg.client]: BytesReceived: 501222 (diff: 0)
[music\sc08_f.ogg.client]: BytesReceived: 162455 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 178839 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 195223 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 211607 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 227991 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 244375 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 260759 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 277143 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 293527 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 309911 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 313342 (diff: 3431)
[music\sc08_f.ogg.client]: BytesReceived: 313342 (diff: 0)
[music\SSQ05_F.ogg.client]: BytesReceived: 15638 (diff: 15638)
[music\SSQ05_F.ogg.client]: BytesReceived: 32022 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 48406 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 64790 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 81174 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 97558 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 113942 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 130326 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 146710 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 162459 (diff: 15749)
[music\SSQ05_F.ogg.client]: BytesReceived: 178843 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 195227 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 211611 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 227995 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 244379 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 260763 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 277147 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 293531 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 309915 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 326299 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 342683 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 359067 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 375451 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 391835 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 408219 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 424603 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 440987 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 457371 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 469073 (diff: 11702)
[music\SSQ05_F.ogg.client]: BytesReceived: 469073 (diff: 11702)
[StaticMeshes\Aden_castle_door_S.usx.client]: BytesReceived: 3614 (diff: 3614)
[StaticMeshes\Aden_castle_door_S.usx.client]: BytesReceived: 3614 (diff: 3614)
您可能会注意到 Diff 并不总是达到 0,有时甚至会变为负数……
我假设在事件处理程序中,除了计算(以及重要的是,在计算之前)之外,您还执行一些操作。
例如下面的代码先进行计算(这需要一点时间),然后导致输出到控制台(文件是从网上随机下载的)
结论是正确的:
但是,只要我们将输出更改为控制台并在某些地方进行计算(即先放一个慢操作)
同时,在输出到控制台的过程中,一个并行线程可以在prev被前一个handler更新之前计算一个新的diff(即相同的prev将用于2个diff),这会导致去同步。结论是:
Отсюда совет - в многопоточном варианте важные и быстрые вычисления помещайте в начало, значения для вывода юзеру запоминайте в локальных переменных (чтобы иъ не могли изменить параллельные потоки). Если это все равно приводит к рассинхрону, то используйте конструкции синхронизации потоков. Например, при потенциальных 2 конкурирующих потоках можно поставить
lock
Но если у вас конкурирующих потоков много, то тогда надо думать основательней. Мне, например, в голову приходят многопоточные очереди, dataflow и прочие вещи. Но это уже тяжелая арта.
И, кстати, я не уверен, что есть вообще какие то гарантии, что эти события идут в хронологическом порядке. Мне кажется поэтому они и не присылают сами дельту, а присылают просто количество скаченных данных.