如何在C# WinForms浏览器的下载表单中获取预估下载时间
计算WebClient下载的预估剩余时间
嘿,要在你的WinForms浏览器下载表单里显示预估下载时间其实很简单,核心思路是通过两次进度更新的差值算出实时下载速度,再用剩余字节数除以速度得到剩余时间。我帮你调整下现有代码:
首先,你需要在窗体类里添加几个私有字段,用来记录上一次进度更新的时间和已下载字节数:
// 记录上一次进度更新的时间 private DateTime _lastProgressUpdateTime; // 记录上一次进度更新时已接收的字节数 private long _lastBytesReceived; // 标记是否是第一次进度更新 private bool _isFirstProgressUpdate = true;
然后修改你的Client_DownloadProgressChanged方法,加入预估时间的计算逻辑:
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { Invoke(new MethodInvoker(delegate () { progressBar1.Minimum = 0; double received = e.BytesReceived; double total = e.TotalBytesToReceive; // 避免总字节为0的异常情况 if (total <= 0) { label7.Text = "下载中..."; progressBar1.Value = 0; return; } double percentage = (received / total) * 100; label7.Text = $"{Math.Truncate(percentage):F0}% complete"; progressBar1.Value = (int)Math.Truncate(percentage); // 计算预估剩余时间 string estimatedTimeText = "计算中..."; if (!_isFirstProgressUpdate) { // 计算两次更新的时间差(秒) TimeSpan timeDiff = DateTime.Now - _lastProgressUpdateTime; double secondsPassed = timeDiff.TotalSeconds; // 计算这段时间内下载的字节数 long bytesDownloadedSinceLastUpdate = e.BytesReceived - _lastBytesReceived; // 避免除以0(比如进度更新太快,时间差几乎为0) if (secondsPassed > 0 && bytesDownloadedSinceLastUpdate > 0) { // 计算每秒下载速度(字节/秒) double bytesPerSecond = bytesDownloadedSinceLastUpdate / secondsPassed; // 剩余字节数 long remainingBytes = e.TotalBytesToReceive - e.BytesReceived; // 计算剩余时间 if (bytesPerSecond > 0) { TimeSpan remainingTime = TimeSpan.FromSeconds(remainingBytes / bytesPerSecond); // 格式化时间为 时:分:秒 的友好格式 estimatedTimeText = $"剩余时间: {remainingTime.Hours:D2}:{remainingTime.Minutes:D2}:{remainingTime.Seconds:D2}"; } else { estimatedTimeText = "下载暂停中..."; } } } else { // 第一次更新时初始化时间和字节数 _lastProgressUpdateTime = DateTime.Now; _lastBytesReceived = e.BytesReceived; _isFirstProgressUpdate = false; } // 把预估时间显示到你需要的Label上,比如label8 label8.Text = estimatedTimeText; // 更新记录的时间和字节数 _lastProgressUpdateTime = DateTime.Now; _lastBytesReceived = e.BytesReceived; })); }
关键逻辑说明:
- 实时速度计算:通过两次进度事件的时间差和字节差来计算速度,比单次计算更精准,能适配下载速度波动的场景。
- 异常防护:加入了总字节为0、时间差为0、速度为0的判断,避免程序崩溃或显示不合理内容。
- 友好格式化:用
D2确保小时、分钟、秒都是两位数(比如02:05:03),显示更规整。
WebClient的DownloadProgressChanged事件触发频率适中,这个计算方式完全够用。如果想要更平滑的显示效果,可以调整记录间隔,但一般来说这样就足够满足需求了。
内容的提问来源于stack exchange,提问作者Mohamad Obeid
相关产品推荐
相关产品推荐

