Click here to Skip to main content
15,904,155 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
Hello Everyone,

Am creating a small project for countdowntimer, i used the below code for the same.

--> Am getting inputs for Hour, Min, Sec via a XML document.
Am able to run my application successfully.

Issue: Seconds timer run like milliseconds and Minutes run crazy. (This is not running in a correct timer format)

The Code Below, please correct me where am missing the logic.

private void timer1_Tick(object sender, EventArgs e)
{
if ((minutes == 0) && (hours == 0) && (seconds == 0))
{
// If the time is over, clear all settings and fields.
// Also, show the message, notifying that the time is over.
timer1.Enabled = false;

lblHr.Text = "00";
lblMin.Text = "00";
lblSec.Text = "00";
CloseApps();

}
else
{
// Else continue counting.
if (seconds < 1)
{
seconds = 59;
if (minutes == 0)
{
minutes = 59;
if (hours != 0)
hours -= 1;

}
else
{
minutes -= 1;
}
}
else
seconds -= 1;
// Display the current values of hours, minutes and seconds in
// the corresponding fields.
if (minutes < 10)
lblMin.Text = "0" + minutes.ToString();
else
lblMin.Text = minutes.ToString();

if (hours < 10)
lblHr.Text = "0" + hours.ToString();
else
lblHr.Text = hours.ToString();
if (seconds < 10)
lblSec.Text = "0" + seconds.ToString();
else
lblSec.Text = seconds.ToString();
}
}



Cheers,
Posted

1 solution

Your whole approach is too bad to consider particular problems. First of all, it reflects the very, very bad trend notorious in many beginners these days: attempting to work with strings representing data instead of data itself. The timer cannot be "running in a correct time format". Timer has nothing to do with the format.

You need to throw out your code, never do such things again, and start from scratch. Here is what you need:

First, understand the difference between time (a point in a time scale expressed by System.DateTime and time duration or interval, expressed by System.TimeSpan — this is the type you have to use: http://msdn.microsoft.com/en-us/library/system.timespan%28v=vs.110%29.aspx[^].

Now, you need to make sure you are not using the timer type System.Windows.Forms.Timer. This type is the easiest to use but totally unsuitable for any action supposed to be more or less periodic, due to prohibitively low time accuracy of this timer. But even with other timer types, you should not rely on its periodic behavior and count the events as you do. Instead, in the handler of your timer event, you should take the real time value from the system. In your case, the most accurate way of doing so is using the class System.Diagnostics.Stopwatch:
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch%28v=vs.110%29.aspx[^].

Its usage is apparent from the documentation; it give you the values of TimeSpan. It allows you to calculate the time from start of the counting.

And only after all these simple calculations are done, you need to present the time span you need to show in you UI in a string. The remaining problem is the notification of your UI (too bad you did not tag what you are using). Let me assume you are making a windows application. Here is a little problem: you cannot call anything related to UI from non-UI thread, and the thread running the handler of your timer event is not the UI thread. You need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
 
Share this answer
 
v3

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