Click here to Skip to main content
15,884,960 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I've made a countdown timer using the timer component to update a label with the remaining time left. The problem is that even though the interval is set to 1 the label doesn't update every millisecond. I've read on different websites that that's because it's not a real time environment.

I've also made a timer that uses DateTime to calculate the difference between the time the timer is started and the actual time, using the same timer component as with the countdown timer. This does update the label every millisecond.

Seeing as the DateTime method does update the label every millisecond I was wondering, is it possible to make a countdown timer with the DateTime method which counts down from a to set amount of time (hours, minutes, seconds, milliseconds)?

What I have tried:

I've searched about this and read several topics on websites, including several on this one, searched Microsoft Docs and MSDN, but I just can't get it to work.
Posted
Updated 3-Feb-19 4:23am

See CodeProject article here: Microsecond and Millisecond C# Timer[^]

And Countdown example here: Countdown timer & Stopwatch - Ivan Popov[^]

Note that the Stopwatch class depends on the system hardware and operating system: Stopwatch.IsHighResolution Field (System.Diagnostics) | Microsoft Docs[^]
 
Share this answer
 
v3
Comments
db211086004 5-Feb-19 7:29am    
This does work great, but can it be used to countdown from a certain set amount of time.

Like I said the method that I use with the calculation with DateTime works fine but I can't set the time correctly.
Timer's don't "fire" at exact intervals, they are processed via the normal Windows Message system which is not a real time system in any way, shape, or form. All you are guaranteed is that the timer tick event will not happen in less that the interval.

So the way to do a countdown is to set a class level DateTime to the end time:
C#
private DateTime endsAt;
...
   endsAt = DateTime.Now.AddMinutes(5);
Then in the Tick handler calculate how much is left:
void countDown_Tick(object sender, EventArgs e)
    {
    int secondsRemaining = (int) (endsAt - DateTime.Now).TotalSeconds;
    myLabel.Text = secondsRemaining.ToString();
    }
 
Share this answer
 
Comments
db211086004 5-Feb-19 7:04am    
But then why does it work for the second method? The one using the DateTime calculation.

Also when I use your method I can't seem to set the correct amount of time (hours, minutes, seconds, milliseconds) and format the into a string. It shows the entire time in the amount set (seconds or milliseconds).
OriginalGriff 5-Feb-19 7:29am    
:sigh:
My code was an example of what you can do: if you look at the TimeSpan class (which subtracting two DateTime values returns) it gives you all the bits you need.

It works because it doesn't matter *when* the tick actually happens - the label is updated with the current time remaining even if it hasn't happened for ten minutes!
db211086004 6-Feb-19 6:59am    
I hope I don't annoy you further by asking another followup question but I've read the TimeSpan class articles on Microsoft Docs and MSDN and I tried to use and change your suggested code but I can't make it work. My label doesn't show a countdown, it just shows the amount of time that has passed from the time I pressed the button (even after I format the string), not the original set time minus the elapsed time.

I've tried to create 2 TimeSpan values and subtract it (I even added them together to see if that made a difference), I've tried to do the same with 2 DateTime values, I've tried to add the time by using TimeSpan.Hours (and doing the same for the minutes, seconds and milliseconds all on the same line of code), I've even found a custom CountDownTimer class and used and changed that but they all don't work.

I either get a label that just shows the total amount of time that has passed, counting upwards (depending on how I code it sometimes with a - symbol in front of it) by using the DateTime method, or the label doesn't get updated at the correct interval (when using a normal timer).
OriginalGriff 6-Feb-19 7:02am    
So show us the exact code you used in your Tick event.
db211086004 7-Feb-19 6:16am    
This is the code for the normal timer I found a in a tutorial:
 milliseconds--;

            if(milliseconds == 0)
            {
                if(seconds > 0 || minutes > 0 || hours > 0)
                {
                    seconds--;
                    milliseconds = 999;

                    if(seconds < 0)
                    {
                        if(minutes > 0)
                        {
                            minutes--;
                            seconds = 59;
                        }
                    }

                    if(minutes < 0)
                    {
                        if(hours > 0)
                        {
                            hours--;
                            minutes = 59;
                        }
                    }
                }
            }

            if(hours == 0 && minutes == 0 && seconds == 0 && milliseconds == 0)
            {
                timer1.Stop();
                MessageBox.Show("You have arrived.");
            }

            label_Timer.Text = string.Format("{0}:{1}:{2}:{3}", hours.ToString().PadLeft(2, '0'), minutes.ToString().PadLeft(2, '0'), seconds.ToString().PadLeft(2, '0'), milliseconds.ToString().PadLeft(2, '0'));

This is the code for the DateTime calculation:
 TimeSpan timeElapsed = DateTime.Now - startTime;

            // DOES THE SAME AS ABOVE BUT WITH A - IN FRONT OF IT
            //TimeSpan timeElapsed = startTime - DateTime.Now;

            label_DateTime.Text = timeElapsed.TotalSeconds.ToString("00:00:00.000");

I have experimented with the DateTime label but never get a real countdown.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900