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

如何计算进度条在指定时间内从0%到100%的加载逻辑?

问题分析与解决方案

一、原代码的时间计算逻辑解释

你提到的原代码确实逻辑绕,它的意图是让进度条整体显示约4秒,但拆分了两部分:

  • 进度条从0到100需要100次Tick,每次间隔30ms,这部分耗时 100×30=3000ms(3秒)
  • 进度条满了之后,再等待35次Tick(实际是第36次Tick时触发判断),这部分耗时 36×30=1080ms
  • 总时长 3000+1080=4080ms,接近4秒,这就是它想凑4秒的逻辑,但计算分散,很容易混淆。

二、针对核心需求的优化方案

你的核心需求是让进度条有可见的加载动画,避免二次加载时一闪而过,类似启动页逻辑,不管实际加载速度,保证进度条至少显示一段时间,同时支持实际加载完成后提前结束动画。

优化思路

  • 设定固定的模拟加载最短时长(比如2秒,可自行调整)
  • 记录定时器启动时间,每次Tick按时间比例更新进度条
  • 监听浏览器加载完成事件,一旦加载完成,立即拉满进度条并结束动画
  • 动画结束或进度条拉满时,隐藏进度条显示浏览器

修改后的完整代码

using System;
using System.Windows.Forms;
using CefSharp;

namespace Weather
{
    public partial class GoogleMapsForm : Form
    {
        private System.Windows.Forms.Timer _loadingMapTimer;
        // 模拟加载的最短时长(单位:毫秒),可自行调整
        private const int SimulateMinLoadDuration = 2000;
        // 定时器启动的时间戳
        private DateTime _timerStartTime;

        public GoogleMapsForm()
        {
            InitializeComponent();

            _loadingMapTimer = new System.Windows.Forms.Timer();
            _loadingMapTimer.Interval = 16; // 接近60fps,动画更平滑
            progressBar1.Maximum = 100;
            _loadingMapTimer.Tick += LoadingMapTimer_Tick;

            WindowState = FormWindowState.Maximized;
            chromiumWebBrowser1.LoadingStateChanged += ChromiumWebBrowser1_LoadingStateChanged;
            chromiumWebBrowser1.Load("D:\\Csharp Projects\\Weather\\map.html");
        }

        private void LoadingMapTimer_Tick(object sender, EventArgs e)
        {
            var elapsedMs = (DateTime.Now - _timerStartTime).TotalMilliseconds;
            
            // 按时间比例计算进度值
            var progress = (int)(elapsedMs / SimulateMinLoadDuration * 100);
            
            // 进度不超过100
            progressBar1.Value = Math.Min(progress, 100);

            // 进度满或达到模拟时长,结束动画
            if (progressBar1.Value >= 100 || elapsedMs >= SimulateMinLoadDuration)
            {
                _loadingMapTimer.Stop();
                progressBar1.Visible = false;
                chromiumWebBrowser1.Visible = true;
            }
        }

        private void ChromiumWebBrowser1_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
        {
            Invoke(new Action(() =>
            {
                if (e.IsLoading)
                {
                    chromiumWebBrowser1.Visible = false;
                    progressBar1.Visible = true;
                    // 启动定时器并记录时间
                    _timerStartTime = DateTime.Now;
                    _loadingMapTimer.Start();
                }
                else
                {
                    // 实际加载完成,立即拉满进度并结束动画
                    if (_loadingMapTimer.Enabled)
                    {
                        _loadingMapTimer.Stop();
                        progressBar1.Value = 100;
                        // 可选:短暂延迟让用户看到满进度,也可以直接隐藏
                        Task.Delay(100).ContinueWith(_ => Invoke(new Action(() =>
                        {
                            progressBar1.Visible = false;
                            chromiumWebBrowser1.Visible = true;
                        })));
                    }
                }
            }));
        }

        private void GoogleMapsForm_Load(object sender, EventArgs e)
        {
        }
    }
}

代码说明

  • 定时器间隔设为16ms,接近60帧每秒,动画更平滑
  • SimulateMinLoadDuration控制进度条最短显示时长,按需调整数值即可
  • 实际加载完成时,会先拉满进度条,可选延迟100ms再切换显示,避免进度条一闪而过
  • 逻辑直观,时间计算集中,避免原代码的分散判断问题

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:17:57