14

スティーブン・トゥーブの記事では:

開発者がタスクに基づいて非同期コードを簡単に記述できるようにするために、.NET 4.5 では監視されない例外の既定の例外動作が変更されています。監視されていない例外によって UnobservedTaskException イベントが発生することはありますが (そうしないと重大な変更になります)、デフォルトではプロセスはクラッシュしません。むしろ、イベント ハンドラーが例外を監視するかどうかに関係なく、イベントが発生した後に例外が食べられることになります。

しかし、私の実験の結果は上記のステートメントと一致しません。以下は私のコードです:

static void Main(string[] args)
{
    DownloadAsync("http://an.invalid.url.com);
}

async static void DownloadAsync(string url)
{
    using (var client = new System.Net.Http.HttpClient())
    {
        string text = await client.GetStringAsync(url);
        Console.WriteLine("Downloaded {0} chars", text.Length);
    }
}

メソッドに無効な URL を渡すため、のメソッドをDownloadAsync()呼び出すと例外がスローされ、アプリケーションがクラッシュします。HttpClientGetStringAsync()

私の質問は次のとおりです。

4

1 に答える 1

35

には例外がありますTask(によって返されるものGetStringAsync)。ただし、awaitは例外を監視してTaskおり、メソッドから伝搬されますDownloadAsync(これは ですasync void)。

async voidメソッドの外に伝播する例外は、異なる動作をします。これらはSynchronizationContext、メソッドの開始時にアクティブだったasync void(この場合はスレッド プールSynchronizationContext) で発生します。これは、観察されない例外とは見なされません。

DownloadAsyncreturnに変更するTaskと、実際には監視されてTaskいない例外が発生し、無視されます (正しく):

static void Main(string[] args)
{
  DownloadAsync("http://an.invalid.url.com);
  Console.ReadKey();
}

async static Task DownloadAsync(string url)
{
  using (var client = new System.Net.Http.HttpClient())
  {
    string text = await client.GetStringAsync(url);
    Console.WriteLine("Downloaded {0} chars", text.Length);
  }
}
于 2013-04-18T23:46:51.820 に答える