Can I use a timer to update a label every x millis

2019-02-25 06:05发布

问题:

This is my code:

Stopwatch timer = new Stopwatch();
timer.Start();
while (timer.ElapsedMilliseconds < 3000) {
    label1.Text = Convert.ToString( timer.ElapsedMilliseconds );
}
timer.Stop();

My intetion was to update the label's text in real time, so if timer.ElapsedMilliseconds == 1350, then label1.Text = 1350. How can I do this? Thanks in advance!

回答1:

You cannot update the UI in a tight loop like that, because while the UI thread is running that code, it isn't responding to paint events. You can do nasty things like "DoEvents()", but please don't... it would be better to just have a Timer and update the UI periodically when the timer event fires; every 50ms would be the absolute fastest I'd go, personally.



回答2:

You better to use System.Windows.Forms.Timer for this, and not Stopwatch()

Even if that timer is less accurate then StopWatch(..) it gives you a good control.

Just example sniplet:

   myTimer.Tick += new EventHandler(TimerEventProcessor);       
   myTimer.Interval = 1350;
   myTimer.Start();

   private void TimerEventProcessor(...){          
     label1.Text = "...";
   }


回答3:

Is this a WinForms app?

The problem is that while your loop runs, it does not give any other tasks (like updating the GUI) any possibility to get done, so the GUI will update the the entire loop is complete.

You can add a quick and "dirty" solution here (if WinForms). Modify your loop like this:

while (timer.ElapsedMilliseconds < 3000) {
  label1.Text = Convert.ToString( timer.ElapsedMilliseconds );
  Application.DoEvents();
}

Now the label should update in between the loop runs.



回答4:

If you want it update every second you could use the modulus operator in your while loop:

Stopwatch timer = new Stopwatch();

timer.Start();

while (timer.ElapsedMilliseconds < 3000) {
    if (timer.ElapsedMilliseconds % 1000 == 0)
    {
        label1.Text = timer.ElapsedMilliseconds.ToString();
    }
}

timer.Stop();

The modulus operator gives the remainder of a division operation, if the milliseconds are a multiple of 1,000 it will return 0.

I'd probably look into using Timers. You do a lot of spinning using the above technique, that may cause your UI to be unresponsive.