在C#中应用程序结束之前,计时器不会触发

Jac*_*rry 3 c# multithreading timer

我在C#中有一个简单的控制台应用程序,它创建一个计时器来向控制台写入文本.然后它等待用户按下一个键.

如果用户在五秒钟之前按下一个键,则应用程序结束,并且计时器永远不会触发.如果用户没有按任何键,则计时器将按预期触发.

为什么计时器创建的线程不会阻止应用程序终止?即使用户按下某个键,我应该如何确保应用程序继续运行?

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.");
    }
Run Code Online (Sandbox Code Playgroud)

jgl*_*uie 6

要使定时器消息始终写出,您可以让主线程等待一旦定时器被触发后发出信号的重置事件.

    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();
    }
Run Code Online (Sandbox Code Playgroud)

至于另一个问题,为什么不阻止申请退出,我会采取刺.在timer_Elapsed()正在从后台线程调用.根据MSDN,后台线程不会保持执行环境的运行.这里有一个很好的讨论.

ThreadPool线程是后台线程,MSDN Timer文档表明在ThreadPool线程上引发了Timer的Elapsed事件,因此应用程序不会等待它,因为它不是前台线程.