C# countdown timer

后端 未结 4 1163
有刺的猬
有刺的猬 2020-12-16 01:39

I\'m trying to make a countdown using C# and show the time in format:

hour:minutes:seconds

I\'ve tried this:

 var minutes          


        
相关标签:
4条回答
  • 2020-12-16 02:02

    You could also use a Timer, as this would handle all the problems like UI-locking. You can use the System.Windows.Forms.Timer-Timer. In the MSDN library you can find samples of the use of it.

    The WinForms-Timer handles also the invoking across the Timer-thread and the UI-thread.

    - SeriTools

    0 讨论(0)
  • 2020-12-16 02:11

    I would use a timer something like this. First a couple of instance variables.

    private int _countDown = 30; // Seconds
    private Timer _timer;
    

    and in the constructor or load event

    _timer = new Timer();
    _timer.Tick += new EventHandler(timer_Tick);
    _timer.Interval = 1000;
    _timer.Start();
    

    and then finally the event handler

    void timer_Tick(object sender, EventArgs e)
    {
        _countDown--;
        if (_countDown < 1)
        {
            _countDown = 30;
        }
        lblCountDown.Text = _countDown.ToString();
    }
    
    0 讨论(0)
  • 2020-12-16 02:12

    You should not use Thread.Sleep here. Thread.Sleep on the UI thread blocks the UI, and using it on another thread leads to additional complexity due to thread synchronization.

    If you have C# 5 or the async CTP you probably can write code very similar to what you did, since you then get a continuation based equivalent of Thread.Sleep that doesn't block the UI.

    In standard C# 4 I'd use a System.Windows.Forms.Timer.

    To start the countdown:

    var minutes = 3; //countdown time
    var start = DateTime.UtcNow; // Use UtcNow instead of Now
    endTime = start.AddMinutes(minutes); //endTime is a member, not a local variable
    timer1.Enabled = true;
    

    In the timer handler you write:

    TimeSpan remainingTime=endTime-DateTime.UtcNow;
    if(remainingTime<TimeSpan.Zero)
    {
       label1.Text = "Done!";
       timer1.Enabled=false; 
    }
    else
    {
      label1.Text = remainingTime.ToString();
    }
    

    For other formatting options see Standard TimeSpan Format Strings.

    One issue that remains with this code is that it will not work correctly if the system clock changes.

    When using DateTime.Now instead of DateTime.UtcNow it will also break when switching from/to daylight saving or changing the timezone. Since you want to identify a certain point in time (and not a display time) you should use UTC instead of local time.

    0 讨论(0)
  • 2020-12-16 02:18

    Your code sets up the variables then goes to sleep for 3 minutes so the if-statement isn't executed until it leaves the sleep state. Either set up a new thread to update the UI or do something like this...

    while (DateTime.now < end) {
      label1.Text = "...";
      Thread.Sleep(#); //Pick a second, or 5 or whatever
    }
    
    label1.Text = "Done!";
    

    With a 2nd thread you can still do stuff in your program while it works. "Done!" will appear once it finishes.

    0 讨论(0)
提交回复
热议问题