从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
,因此文档的后半部分适用:
在这些事件处理程序中抛出的例外播种机被传播回去 到调用线程,如以下示例所示。