async/await - Task と void のどちらを返すべきか? 質問する

async/await - Task と void のどちらを返すべきか? 質問する

どのようなシナリオで使用したいのか

public async Task AsyncMethod(int num)

の代わりに

public async void AsyncMethod(int num)

私が考えられる唯一のシナリオは、タスクの進行状況を追跡する必要がある場合です。

また、次のメソッドでは、async および await キーワードは不要ですか?

public static async void AsyncMethod2(int num)
{
    await Task.Factory.StartNew(() => Thread.Sleep(num));
}

ベストアンサー1

  1. 通常は、 を返す必要があります。主な例外は、戻り値の型 (イベント用)が必要Task場合です。呼び出し元をタスクにすることを禁止する理由がないのであれば、なぜ禁止するのでしょうか。voidawait

  2. 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://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

おすすめ記事