I have simple Console application in C# that creates a timer to write text to the Console. Then it waits for the user to press a key.
If the user presses a key before five seconds elapse, then the application ends, and the timer never fires. If the user does not press a key, then the timer fires as expected.
Why does the thread that the timer creates not keep the application from terminating? How should I ensure that the application keeps running even if the user presses a key?
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(5000);
timer.Interval = 5000; // 5 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.AutoReset = true;
timer.Start();
Console.ReadKey();
}
public static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("Timer Fired.");
}
To get the timer message to always write out, you can have the main thread wait on a reset event that is signaled once the timer is fired.
static ManualResetEvent timerFired = new ManualResetEvent(false);
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(5000);
timer.Interval = 5000; // 5 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.AutoReset = true;
timer.Start();
Console.ReadKey();
// This call will return only after timerFired.Set() is
// called. So, if the user hits a key before the timer is
// fired, this will block for a little bit, until the timer fires.
// Otherwise, it will return immediately
timerFired.WaitOne();
}
public static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("Timer Fired.");
timerFired.Set();
}
As for the other question, why doesn't it prevent the application from exiting, I'll take a stab. The timer_Elapsed() is being called from a background thread. According to MSDN, background threads don't keep the execution environment running. There's a nice discussion here.
ThreadPool threads are background threads, and MSDN Timer documentation indicates that the Timer's Elapsed event is raised on a ThreadPool thread, so the application wouldn't wait for it as it's not a foreground thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With