一般に、火をつけて忘れるasync void
タスクを開始するためのメソッド。保留中のタスクの追跡がなく、そのようなメソッド内でスローされる可能性のある例外を処理するのが難しいためです。
通常、async void
イベントハンドラも同様ですか?たとえば、
private async void Form_Load(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
このように書き換えることができます:
Task onFormLoadTask = null; // track the task, can implement cancellation
private void Form_Load(object sender, System.EventArgs e)
{
this.onFormLoadTask = OnFormLoadTaskAsync(sender, e);
}
private async Task OnFormLoadTaskAsync(object sender, System.EventArgs e)
{
await Task.Delay(2000); // do async work
// ...
}
再入可能性に加えて、非同期イベントハンドラーの水中岩は何ですか?
ガイドラインは、async void
exceptイベントハンドラで使用する場合は、async void
イベントハンドラでOKです。
とはいえ、ユニットテストの理由で、すべてのasync void
メソッド。例えば。、
public async Task OnFormLoadAsync(object sender, EventArgs e)
{
await Task.Delay(2000);
...
}
private async void Form_Load(object sender, EventArgs e)
{
await OnFormLoadAsync(sender, e);
}
一般に、非同期voidイベントハンドラーも避けるべきですか?
一般的に、イベントハンドラーは、無効な非同期メソッドが潜在的なコード臭ではない1つのケースです。
さて、何らかの理由でタスクを追跡する必要がある場合、説明する手法は完全に合理的です。
はい、通常、イベントハンドラーの非同期ボイドが唯一のケースです。詳細については、チャンネル9のすばらしいビデオをご覧ください。The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".
ReSharperを使用する場合、無料の ReCommended Extension が役立ちます。 「非同期void」メソッドを分析し、不適切に使用された場合に強調表示します。この拡張機能は、非同期voidのさまざまな使用法を区別し、ここで説明する適切なクイックフィックスを提供できます。 ReCommended-Extension wiki 。