Resolved Display time not according to actual timing

mfwoo

Member
Joined
Nov 2, 2020
Messages
7
Programming Experience
10+
I create a timer for count down (set to 5 secs) for photo taking using my webcam.
It start with 5, 4, 3, 2, 1 and when its reaches 0, I will call the webcam function to snap the picture.
The number of seconds is display via a label.
Problem with the timer, it was not exactly 1 seconds apart and I can see the screen refresh stops for more than 2 seconds or more before it number in the label changed.

Anyone can help ?

C#:
 public System.Windows.Forms.Timer tmrTakePhotoCountdown = new System.Windows.Forms.Timer();
 tmrTakePhotoCountdown.Interval = 1000;
 tmrTakePhotoCountdown.Tick += new System.EventHandler(this.tmrTakePhoto_Tick);
 
  private void GotoTakePhoto()
  {
        initCamera();
        // start countdown
        int takePhotoCountDown = 5; //5 secs
        CountDown(takePhotoCountDown);
  }
 
  DateTime start;
  int timeLeft;
  public void CountDown(int seconds)
  {
     start = DateTime.Now;
     timeLeft = seconds;

     tmrTakePhotoCountdown.Start();

     lblCountdown.Visible = true;             //label to display seconds to phototake
     lblCountdown.Text = timeLeft.ToString();
  }

   private void tmrTakePhoto_Tick(object sender, EventArgs e)
   {
       lblCountdown.Text = timeLeft.ToString();
       timeLeft -= 1;
       if (timeLeft < 0)
       {
           tmrTakePhotoCountdown.Stop();
           videoCaptureDevice.Stop();
           lblCountdown.Visible = false;
           pixTakePhotoAccept.Visible = true;
           pixTakePhotoRetake.Visible = true;
           pixTakePhotoCancel.Visible = true;
       }
   }
 
Solution
You're doing it very wrong. You should not be using a Timer to measure time. You should be using a Stopwatch. The Timer gives you an opportunity to act by raising an event, much like a Button does, but without the need for user intervention. The two actions you should be performing are using a Stopwatch to measure the remaining time and displaying it, then taking a picture if time has expired.
  1. Declare a field of type TimeSpan and set it to the amunt of tiime you want to count down, e.g. private TiimeSpan countdownTiime = TiimeSpan.FromSeconds(5);
  2. Use a small Interval value for your Timer...

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
2,135
Location
Chesapeake, VA
Programming Experience
10+
The WinForms Timer is not meant to be precision timer.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
2,135
Location
Chesapeake, VA
Programming Experience
10+
I can see the screen refresh stops for more than 2 seconds or more before it number in the label changed
Recall the law of sampling: you need to set your refresh to be double of your target precision. So make your timer fire every 500 ms, instead of the current 1000 ms.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,277
Location
Sydney, Australia
Programming Experience
10+
You're doing it very wrong. You should not be using a Timer to measure time. You should be using a Stopwatch. The Timer gives you an opportunity to act by raising an event, much like a Button does, but without the need for user intervention. The two actions you should be performing are using a Stopwatch to measure the remaining time and displaying it, then taking a picture if time has expired.
  1. Declare a field of type TimeSpan and set it to the amunt of tiime you want to count down, e.g. private TiimeSpan countdownTiime = TiimeSpan.FromSeconds(5);
  2. Use a small Interval value for your Timer, e.g. 100.
  3. When you start the Tiimer, start a new Stopwatch as well.
  4. When the Timer ticks, subtract the Elapsed time of the Stopwatch from your total time and display the number of seconds remaining.
  5. When the amount of time remaining reaches zero, stop the Timer and do what you need to do.
 
Solution
Top Bottom