Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控制台应用程序上的Timers.Timer与Threading.Timer_C#_Multithreading_Timer - Fatal编程技术网

C# 控制台应用程序上的Timers.Timer与Threading.Timer

C# 控制台应用程序上的Timers.Timer与Threading.Timer,c#,multithreading,timer,C#,Multithreading,Timer,我注意到Timer.Timer和Threading.Timer在控制台应用程序上的行为不同。在ThreadingTimer的回调中,如果我抛出异常,它将使应用程序崩溃。但是,如果我在TimerTimer Expressed处理程序中抛出异常,它将不会使其崩溃 这两个方法都在线程池中的工作线程上执行。我推测ThreadingTimer以某种方式将异常传播到主线程,而TimerTimer则不是 我在MSDN中找不到这种行为的解释,你能帮我一下吗 下面是一个行为示例: class Program {

我注意到Timer.Timer和Threading.Timer在控制台应用程序上的行为不同。在ThreadingTimer的回调中,如果我抛出异常,它将使应用程序崩溃。但是,如果我在TimerTimer Expressed处理程序中抛出异常,它将不会使其崩溃

这两个方法都在线程池中的工作线程上执行。我推测ThreadingTimer以某种方式将异常传播到主线程,而TimerTimer则不是

我在MSDN中找不到这种行为的解释,你能帮我一下吗

下面是一个行为示例:

class Program
{
    static void Main(string[] args)
    {
        var healthMonitor = new HealthMonitor();
        healthMonitor.Start();
        Console.ReadLine();
    }
}

internal class HealthMonitor
{
    private Timer _timersTimer;
    private System.Threading.Timer _threadingTimer;

    public void Start()
    {
        StartTimersTimer(); 
        // StartThreadingTimer();
    }

    private void StartThreadingTimer()
    {
        _threadingTimer = new System.Threading.Timer(
            ThreadingTimerCallback,
            null,
            TimeSpan.FromMilliseconds(5000),
            TimeSpan.FromMilliseconds(5000));
    }

    private void ThreadingTimerCallback(object state)
    {
        Console.WriteLine("Throwing from ThreadingTimer..");
        throw new Exception("Exception from ThreadingTimer");
    }

    private void StartTimersTimer()
    {
        Console.WriteLine("Starting timers...");
        _timersTimer = new Timer(5000);
        _timersTimer.Elapsed += TimersTimer_Elapsed;
        _timersTimer.Enabled = true;
    }

    private void TimersTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Throwing from TimersTimer...");
        throw new Exception("Exception from TimersTimer");
    }
}

正如HansPassant、mike z和Cody Gray所说,答案在MSDN中,特别是:

计时器组件捕获并抑制由引发的所有异常 已过去事件的事件处理程序。这种行为受到法律的约束 .NET Framework未来版本中的更改


有趣的是,这种行为是从.NET1.1开始出现的,所以看起来变化不是迫在眉睫的

在.NET1.0中,System.Timers.Timer是一个更易于使用的计时器类。不幸的是,当时更容易使用意味着比现在更多。太多了,在经过的事件处理程序中引发的任何异常都会在没有任何诊断的情况下被吞噬。这要求您自己编写try/catch或避免类。您可以很容易地在中看到System.Timers.Timer只是包装了System.Threading.Timer。它只捕获在引发经过的事件时抛出的所有异常。您不必查看引用源,这是事实。感谢HansPassant、mike z、Cody Gray。这就是为什么我强烈建议不要使用
System.Timers.Timer
。这是一个防虫洞。