【发布时间】:2022-11-02 22:06:59
【问题描述】:
我试图向用户展示正确的下载速度,但我的应用程序下载同时是一堆小文件,为了加快速度,我正在使用Parallel.ForEach。但是我无法计算正确的下载速度。使用我当前的代码,我基本上是在计算平均下载速度,而不是当前下载的速度。因为每次下载完成时它都会更新 UI。当我使用正常的foreach 时,我可以正确计算但速度很慢。如何使用多个线程和多个文件正确显示下载的 Mbps?
注意:这个应用程序是 WPF,但我几乎没有使用任何 MVVM。这是我第一次使用 WPF,目前我只是想制作一个功能不错的东西。
下载功能
var stopwatch = new Stopwatch();
stopwatch.Start();
DownloadController.stopwatch.Start();
DownloadController.IsDownloadStarted = true;
DownloadController.IsDownloadInProgress = true;
Parallel.ForEach(downloadList, new ParallelOptions { MaxDegreeOfParallelism = 5 }, file =>
{
try
{
DownloadController.LastDownloadingFileName = file.FileName;
GET_DownloadFile(file.FileName, file.LastUpdate.UnixTimeStampToDateTime()).GetAwaiter().GetResult();
logger.Info("Download", file.FileName, "Downloading file completed");
}
catch (Exception ex)
{
lock (_failedDownloads)
{
_failedDownloads.Add(file);
}
logger.Exception(ex, "Download", file.FileName, file.LastUpdate, file.Size, $"Failed to download file");
}
});
进度改变事件
public static void DownloadProgressChangedEvent(object sender, DownloadProgressChangedEventArgs e)
{
MainWindow._dispatcher.BeginInvoke(new Action(() =>
{
ButtonProgressAssist.SetValue(MainWindow.This.Prog_Downloading, ProgressValue);
ButtonController.ButtonPlay_Downloading();
if (e.ProgressPercentage == 100)
{
DownloadedSize += e.TotalBytesToReceive;
var downloadSpeed = string.Format("{0} ", (DownloadedSize / 1024.0 / 1024.0 / stopwatch.Elapsed.TotalSeconds).ToString("0.0"));
var text1 = $"({ProgressValue}% - {DownloadedFileCount}/{TotalFileUpdateCount}) @ {downloadSpeed}MB/s {EasFile.GetFileNameWithExtension(LastDownloadingFileName)} ";
MainWindow.This.DownloadTextBlock.Text = text1;
}
}));
}
进度完成事件
public static void DownloadProgressCompletedEvent(object? sender, AsyncCompletedEventArgs e)
{
if (!e.Cancelled)
{
DownloadedFileCount++;
}
}
我尝试使用PerformanceCounter 来查看我当前应用程序的网络使用情况,但它只显示特定网络上所有使用情况的使用情况。
【问题讨论】:
-
只需打印“大约剩下三个烦人”,以一秒的增量将进度条增加到 90%,完成后将其移动到 100%。这是一个几十年前的问题,你无法解决。如果您事先不知道需要下载多少字节,则永远无法给出准确的估计。
-
您可以创建一个
Progress类并以线程安全的方式跟踪此类中总下载字节的状态,但除非您的下载需要很长时间,否则在 UI 中显示一个不确定的进度条通常就足够了。 -
@CodeCaster 我确实知道每次下载将有多少字节。
-
@mcy 主要下载大约 20 300MB 大约 20 个文件。但客户端也可以一次下载大约 7000+ 个文件,具体取决于客户端是否拥有所有文件。
-
那么,保持每个文件的进度?