【问题标题】:how to pause progressbar in c#如何在c#中暂停进度条
【发布时间】:2017-02-23 07:26:52
【问题描述】:

我有一个在 20 分钟内完成的进度条。我使用计时器控制来增加进度条。现在我希望每 5 分钟后它暂停 2 分钟,在这些分钟内没有增加进度,2 分钟后它再次恢复。怎么做?这是我的代码

private void timer1_Tick(object sender, EventArgs e)
{
    circularProgressBar1.Increment(1);
    circularProgressBar1.Text = circularProgressBar1.Value.ToString();
    circularProgressBar1.SuperscriptText = "%";
}

这工作正常,但如何在每 5 分钟后自动暂停。

【问题讨论】:

  • Interval 的值是多少?
  • 1200000 是我的区间值
  • 您是否希望它在运行时运行得更快,以便在 20 分钟内完成?还是应该花更长的时间?
  • Interval 的 1200000 表示 20 分钟。从您的代码来看,我猜想您的 Interval 为 0.2 分钟 = 12000...您的进度条不是从 0 开始吗​​?
  • 进度条从 0 开始。现在 20 分钟内完成。但显然,当我暂停 2 分钟时,将需要更长的时间才能完成。但这无关紧要。我只想在每 5 分钟后暂停 2 分钟

标签: c# timer progress-bar


【解决方案1】:

我建议你记住开始时间,并用它来计算每个 Tick 中经过的时间。然后您可以检查您是否在休息间隔之外,即您是否在第一次休息之前 (elapsed.Minutes < activeMinutes) 或者您是否在第一次休息之后 (elapsed.Minutes >= activeMinutes + pauseMinutes)并且不在另一个休息时间间隔(elapsed.Minutes % (activeMinutes + pauseMinutes) < activeMinutes))。

完整的代码如下所示:

private DateTime _startTime;
private int activeMinutes = 5;
private int pauseMinutes = 2;
private Timer _timer;

private void StartTimer()
{
    if(_timer != null)
    {
        // detach event handler from old timer before creating a new one
        _timer.Tick -= timer1_Tick;
    }
    _timer = new Timer();
    _timer.Interval = 12000;
    _timer.Tick += timer1_Tick;
    _timer.Start();
    _startTime = DateTime.Now;
}

private void timer1_Tick(object sender, EventArgs e)
{    
    TimeSpan elapsed = DateTime.Now.Subtract( _startTime );
    if( elapsed.Minutes < activeMinutes ||
       (elapsed.Minutes >= activeMinutes + pauseMinutes &&
        elapsed.Minutes % (activeMinutes + pauseMinutes) < activeMinutes))
    {
        circularProgressBar1.Increment(1);
        circularProgressBar1.Text = circularProgressBar1.Value.ToString();
        circularProgressBar1.SuperscriptText = "%";
    }
}

【讨论】:

    【解决方案2】:

    您可以使用 TimeSpan 并在每个计时器滴答时向此 TimeSpan 添加间隔。当你达到 5 分钟并重新开始时修改计时器。这是示例,它未经测试,因此可能需要一些调试。

    我建议将计时器的初始间隔设置为 1000 毫秒,以便进度条每秒更新一次,尽管您也可以设置更长的间隔。

    private double interval = 1000; // one second interval so progress bar updates every second.
    private TimeSpan elapsed; // time span that reaches 5 minutes. this will reset to 0 after 5 minutes.
    private TimeSpan totalElapsed; // total time passed. used to set value of progress bar
    private bool progressPaused; // flag, true if progressbar is at 2 min pause, otherwise false
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        const int fiveMinutes = 5*1000*60;
        const int twoMinutes = 2*1000*60;
        const int totalMinutes = 20*1000*60;
    
        var timer = (Timer) sender; // assuming Timer is System.Timers.Timer
    
        if(timer.Enabled == false) return;
    
        if (progressPaused) 
        {
            // progressbar was paused. prepare to start again
    
            timer.Enabled = false;
            timer.AutoReset = true;
            timer.Interval = interval; // previous interval
            progressPaused = false;
            timer.Enabled = true;
            return;
        }
    
        // add interval of timer to TimeSpans
        totalElapsed = totalElapsed.Add(TimeSpan.FromMilliseconds(timer.Interval));
        elapsed = elapsed.Add(TimeSpan.FromMilliseconds(timer.Interval));
    
        if (elapsed.Milliseconds > fiveMinutes) // if we reached 5 minutes
        {
            elapsed = default(TimeSpan); // reset timespan from 5 min to 0
            timer.Enabled = false;
            timer.AutoReset = false; // auto reset should be off because we only pause once per 2 minutes. (although this may have no effect)
            interval = timer.Interval;
            timer.Interval = twoMinutes; // two minute pause
            progressPaused = true; // set falg
            timer.Enabled = true;
        }
    
        circularProgressBar1.Value = (int)(totalElapsed.Milliseconds/(double)totalMinutes*100); // calculate new progressbar value. (elapsed/total*100)
        circularProgressBar1.Text = circularProgressBar1.Value.ToString();
        circularProgressBar1.SuperscriptText = "%";
    }
    

    【讨论】:

    • 此代码不起作用。进度条卡在 0% 并且没有增加
    • 删除此行并再次测试。 timer.AutoReset=false
    【解决方案3】:

    计算to date startdate(在进度开始之前获取)和enddate(每次进入timer1_Tick时获取)之间的差异

    DateTime startTime = DateTime.Now;
    
    
    private void timer1_Tick(object sender, EventArgs e)
        {
    DateTime endTime = DateTime.Now
    
    TimeSpan span = endTime.Subtract( startTime );
    if(span.Minutes % 5 == 0){
            circularProgressBar1.Increment(1);
            circularProgressBar1.Text =    circularProgressBar1.Value.ToString();
            circularProgressBar1.SuperscriptText = "%";
     }
    }
    

    【讨论】:

    • 这将运行一分钟,然后暂停四分钟。
    【解决方案4】:

    定时器定时器;

        int countTime;
        bool breakReached;
        int breakTime;
        int breakLength;
        int countToFinish;
        int finishTime;
    
        public Form1()
        {
            InitializeComponent();
            timer = new Timer();
            timer.Interval = 1000;
    
            breakTime = 300; // in sek
            breakLength = 120; // in sek
            finishtime = 1200;
            breakReached = false;
            timer.Tick += Timer_Tick;
            timer.Start();
        }
    
        private void Timer_Tick(object sender, EventArgs e)
        {
            if (countTime != breakTime && breakReached != true)
            {
                progressBar1.Increment(1);
                progressBar1.Text = progressBar1.Value.ToString();
            }
            else
            {
                //break was reached
                breakReached = true;
                countTime = 0;
                while(countTime != breakLength)
                {
                    //do the 2 min break
                }
                breakReached = false;
            }
            countTime++;
            countToFinish ++;
            if(countToFinish == finishTime)
            {//its done}
        }
    

    【讨论】:

    • 要拥有 20 分钟的“活动时间”,您应该将间隔设置为 12000。否则,在 100 秒的“活动时间”后达到 100%,这使得进度条在 1 分 40 秒内完成,甚至没有中断: -)
    • 一旦countTime 等于breakTime 你进入else 分支并陷入while 循环。然后你永远不会离开它,因为所有未来的调用也会转到else 分支(因为breakReached 是真的)并且没有人会增加countTime 或将breakReached 设置为假。所以从第一次中断开始,你就在无限循环中累积事件处理程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多