Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timer Does Not Fire Before Application Ends in C#

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.");
    }
like image 456
Jacob Quisenberry Avatar asked Mar 28 '26 17:03

Jacob Quisenberry


1 Answers

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.

like image 145
jglouie Avatar answered Mar 31 '26 10:03

jglouie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!