2017-09-12 19 views
0

Microsoftのドキュメントでは、System.Timers.Timer経過メソッドはすべての例外を呑み込むはずです。例外がスローされるとSystem.Timers.Timerがクラッシュする

Timerコンポーネントは、Elapsedイベントのイベントハンドラによってスローされたすべての例外をキャッチして抑制します。アプリケーションがクラッシュ例外が生成さasync void方法を使用して加入しかしhttps://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

。下記のコードを参照してください。

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さんがコメントした行はそうです。

これはなぜですか?

+2

ヤック、あたかも良いフィーチャーのように鳴らしています。これは.NET 1.0の最悪の決定の間で高く評価されています。そして確かに、動作しません、イベントを発生させるコードは、タスクが完了するまでにはずっと去っています。それで何も捕まえられない。 async-voidメソッドはfire-and-forgetコードです。 –

+0

私は同意する、彼らはすべてスローする必要があります。しかし、私は非同期を待っているときに驚いた。 –

+0

['async void'例外は通常の手段で捕捉できません](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx) –

答えて

3

The link you provided状態:

Timerコンポーネントの漁獲量とElapsedイベントのために イベントハンドラによってスローされるすべての例外を抑制することができます。この現象は、.NET Frameworkの将来のリリースで 変更の影響を受けます。ただし、 は非同期に実行されるイベントハンドラには該当せず、 にはawait演算子(C#で)またはAwait演算子(Visual Basic)が含まれています。これらのイベントハンドラでスローされた例外は、次の例のように、 を呼び出しスレッドに戻して伝播します。 非同期メソッドでスローされる例外の情報については、 例外処理(タスク並列ライブラリ)を参照してください。

あなたはawaitを使用しているので、その後のドキュメントの後半部分が適用されます。次の例が示すように、これらのイベントハンドラでスロー

例外は、バック 呼び出し元のスレッドに伝播されます。

関連する問題