You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:37:39