25

、、、の 3 つのタスクがaあるbとしcます。3 つすべてが、1 ~ 5 秒のランダムな時間に例外をスローすることが保証されています。次に、次のコードを記述します。

await Task.WhenAny(a, b, c);

これにより、最終的には、最初に失敗したタスクから例外がスローされます。ここには何もないためtry...catch、この例外はコード内の別の場所にバブルアップします。

残りの 2 つのタスクが例外をスローするとどうなるでしょうか。これらの監視されていない例外は、プロセス全体を強制終了させる原因になるのではないでしょうか? つまり、使用する唯一の方法はブロックWhenAny内であり、try...catch続行する前に残りの 2 つのタスクを何らかの方法で観察するということですか?

フォローアップ: Async Targeting Pack を使用した .NET 4.5.NET 4.0 の両方に回答を適用したいと思います(ただしTaskEx.WhenAny、その場合は明らかに使用しています)。

4

2 に答える 2

27

残りの 2 つのタスクが例外をスローするとどうなるでしょうか。

これらTaskの は障害状態で完了します。

これらの監視されていない例外は、プロセス全体を強制終了させる原因になるのではないでしょうか?

もう違います。

.NET 4.0 では、Taskデストラクタは監視されていない例外を に渡し、TaskScheduler.UnobservedTaskException未処理の場合はプロセスを終了させて​​いました。

.NET 4.5 では、この動作が変更されました。現在、監視されていない例外は に渡されますがTaskScheduler.UnobservedTaskException、未処理の場合は無視されます。

于 2012-10-01T17:56:34.743 に答える
5

はい、残りのタスク例外は観察されません。.NET 4.5より前では、それらを観察する義務があります(.NET 4.5での状況はわかりませんが、状況は変わりました)。

私は通常、次のようなファイア アンド フォーゲット タスクのヘルパー メソッドを自分で作成します。

    public static void IgnoreUnobservedExceptions(this Task task)
    {
        if (task.IsCompleted)
        {
            if (task.IsFaulted)
            {
                var dummy = task.Exception;
            }
            return;
        }

        task.ContinueWith(t =>
            {
                var dummy = t.Exception;
            }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
    }

運用アプリにログを含めることができます。

于 2012-10-01T17:48:22.037 に答える