非同期処理中に発生した例外をキャッチする際にちょっとはまったのでメモします。
非同期処理中に発生した例外をキャッチしたい場合、その非同期処理を await
している場合と、Wait()
で同期処理のように扱った場合とで発生する例外が異なり、ちょっとはまりました。
Wait していた場合
例えば以下のように Wait()
していた場合に InvalidOperationException
が発生したとします。
public static void Main()
{
try
{
Task.Run(() =>
{
throw new InvalidOperationException();
}).Wait();
}
catch (InvalidOperationException ex)
{
Console.WriteLine("InvalidOperationException!");
Console.WriteLine(ex.GetType());
Console.WriteLine(ex.InnerException?.GetType());
}
catch (Exception ex)
{
Console.WriteLine("Exception!");
Console.WriteLine(ex.GetType());
Console.WriteLine(ex.InnerException?.GetType());
}
Console.ReadKey();
}
出力結果
Exception!
System.AggregateException
System.InvalidOperationException
結果からわかる通り、 InvalidOperationException
ではキャッチできません。
例外の型は AggregateException
になっており、InnerException
に InvalidOperationException
が格納されていました。
await していた場合
非同期処理を await
していた場合は InvalidOperationException
でキャッチできます。
public static async Task Main()
{
try
{
await Task.Run(() =>
{
throw new InvalidOperationException();
});
}
catch (InvalidOperationException ex)
{
Console.WriteLine("InvalidOperationException!");
Console.WriteLine(ex.GetType());
Console.WriteLine(ex.InnerException?.GetType());
}
catch (Exception ex)
{
Console.WriteLine("Exception!");
Console.WriteLine(ex.GetType());
Console.WriteLine(ex.InnerException?.GetType());
}
}
出力結果
InvalidOperationException!
System.InvalidOperationException