System.Timers.Timer在异常上崩溃



从Microsoft文档中 System.Timers.Timer经过的方法应吞噬所有异常。

计时器组件捕获并抑制事件处理程序为经过的事件抛出的所有异常。

https://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

但是,使用async void方法订阅时,产生了崩溃应用程序的异常。请参阅以下代码:

class Program
{
    static void Main(string[] args)
    {
        Timer timer = new Timer(100);
        //timer.Elapsed += On_ElapsedSync; //A
        //timer.Elapsed += On_ElapsedAsync; //B
        timer.Elapsed += On_ElapsedAsyncVoid; //C
        timer.Start();
        Console.WriteLine("Running...");
        Console.ReadLine();
    }
    private static void On_ElapsedSync(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Throwing...");
        throw new Exception("My Exception");
    }
    private static void On_ElapsedAsync(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Throwing...");
        Task.Run(() => throw new Exception("Async Exception"));
    }
    private static async void On_ElapsedAsyncVoid(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Throwing...");
        await Task.Run(() => throw new Exception("Async Exception"));
    }
}

行评论A和B不会崩溃。该行评论了C。

为什么会这样?

您提供的链接状态:

计时器组件捕获并抑制所有异常。 经过的事件的活动处理程序。这种行为受 更改.NET框架的未来版本。但是请注意, 对于异步执行和 包括等待运营商(在C#中)或等待操作员(在Visual中 基本的)。在这些活动处理程序中抛出的例外是繁殖的 如以下示例所示,到调用线程。更多 有关抛出异步方法的例外的信息,请参阅 异常处理(任务并行库)。

由于您使用的是await,因此文档的后半部分适用:

在这些事件处理程序中抛出的例外播种机被传播回去 到调用线程,如以下示例所示。

最新更新