通常、 を返したいと思うでしょうTask
。主な例外は、(イベントの) 戻り値の型が必要な場合です。void
発信者がawait
あなたの仕事をすることを禁止する理由がないのなら、なぜそれを許可しないのですか?
async
返されるメソッドvoid
は、別の側面で特別です。トップレベルの非同期操作を表し、タスクが例外を返したときに適用される追加のルールがあります。違いを示す最も簡単な方法は、例を使用することです。
static async void f()
{
await h();
}
static async Task g()
{
await h();
}
static async Task h()
{
throw new NotImplementedException();
}
private void button1_Click(object sender, EventArgs e)
{
f();
}
private void button2_Click(object sender, EventArgs e)
{
g();
}
private void button3_Click(object sender, EventArgs e)
{
GC.Collect();
}
f
の例外は常に「監視」されます。最上位の非同期メソッドを終了する例外は、他の未処理の例外と同様に単純に処理されます。g
の例外は観察されません。ガベージ コレクターがタスクをクリーンアップするようになると、タスクの結果が例外であり、誰もその例外を処理していないことがわかります。その場合、TaskScheduler.UnobservedTaskException
ハンドラーが実行されます。これを絶対に許してはいけません。あなたの例を使用するには、
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
はい、使用async
し、await
ここで、例外がスローされた場合でもメソッドが正しく機能することを確認します。
詳細については、https ://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming を参照してください。