Taskを返すことができるのに、なぜasyncとreturn awaitを使用するのか 直接?質問する

Taskを返すことができるのに、なぜasyncとreturn awaitを使用するのか 直接?質問する

次のような書き方が適したシナリオはありますか?

public async Task<SomeResult> DoSomethingAsync()
{
    // Some synchronous code might or might not be here... //
    return await DoAnotherThingAsync();
}

これの代わりに:

public Task<SomeResult> DoSomethingAsync()
{
    // Some synchronous code might or might not be here... //
    return DoAnotherThingAsync();
}

意味があるでしょうか?

内部呼び出しからreturn await直接戻ることができるのに、なぜコンストラクトを使用するのでしょうか?Task<T>DoAnotherThingAsync()

非常に多くの場所でこのコードが使用されているのでreturn await、何か見逃しているのではないかと思います。しかし、私の理解では、この場合、async/await キーワードを使用せず、直接 Task を返すことは機能的に同等です。なぜ追加awaitレイヤーのオーバーヘッドを追加するのでしょうか?

ベストアンサー1

return通常のメソッドとreturn awaitメソッドasyncが異なる動作をする、巧妙なケースが 1 つあります。それは、 と組み合わせた場合using(または、より一般的には、ブロックreturn await内のany と組み合わせた場合try) です。

次の 2 つのバージョンのメソッドを検討してください。

Task<SomeResult> DoSomethingAsync()
{
    using (var foo = new Foo())
    {
        return foo.DoAnotherThingAsync();
    }
}

async Task<SomeResult> DoSomethingAsync()
{
    using (var foo = new Foo())
    {
        return await foo.DoAnotherThingAsync();
    }
}

最初のメソッドは、メソッドが返されるとすぐにオブジェクトDispose()を破棄しますが、これは実際に完了するずっと前になる可能性があります。つまり、最初のバージョンはおそらくバグがある (破棄が早すぎるため) 一方、2 番目のバージョンは正常に動作します。FooDoAnotherThingAsync()Foo

おすすめ記事