19

サード パーティの Web サービス呼び出しをラップするライブラリを作成しており、ライブラリで新しい async/await 機能を使用しようとしています。次の例の async/await キーワードの正しい使い方はどれですか?

public class MyApi
{
    public Task<ApiResult> DoSomethingAsync()
    {
        return this.DoSomethingCore();
    }

    public async Task<ApiResult> DoSomethingElseAsync()
    {
        return await this.DoSomethingCore();
    }

    private async Task<ApiResult> DoSomethingCore()
    {
        var httpClient = new HttpClient();
        var httpResponseMessage = await httpClient.GetAsync("some url");
        var rawResultText = await httpResponseMessage.Content.ReadAsStringAsync();
        return new ApiResult(rawResultText);        
    }
}

呼び出し元が DoSomethingAsync メソッドを待機できるようにするには、そのメソッドにも async キーワードと await キーワードを追加する必要がありますか? それとも Task を返すのでそのままでいいのでしょうか? この種の入れ子のより良いパターンはありますか?

DoSomethingAsync メソッドが正しい方法だと思いますが、正しいですか? ライブラリを構築するとき、 DoSomethingElseAsync は間違ったアプローチのように思えます。

4

2 に答える 2

16

Taskどこから来たかに関係なく、どんなものでも待つことができます。

なぜ単にDoSomethingAsyncを呼び出すDoSomethingCoreのかはわかりません。DoSomethingAsyncasyncawait

ライブラリ メソッドで使用する必要がある一般的な規則もあります。ConfigureAwait(false)

編集:を使用する必要がない場合はawait、メソッドを作成しないでくださいasyncasyncいくらかのオーバーヘッドが追加されます (Stephen Toub の Zen of Async Performance ビデオについては、Channel9 を確認してください)。Task(like ) を返すことができる場合はDoSomethingAsync、そのようにします。

于 2012-08-02T14:24:00.523 に答える
3

以下の定式化は機能しますが、追加のオーバーヘッドが発生する可能性があります (追加の async/await メソッドのセカンダリ コールバックがあるため)。

public async Task<ApiResult> DoSomethingElseAsync()
{
    return await this.DoSomethingCore();
}

メソッドを「非同期」として実装しなくても、そのタスクを他の場所でいつでも待機できるため、タスクを直接返す方が簡単です。Async/await は、'yield return' の使用によく似ています。「生成」を実装するためにコンパイラの魔法を実行しますが、列挙自体は実装方法を気にしません。同様に、「await」呼び出しは、awaitable である限り、awaitable がどのように機能するかは気にしません。

于 2012-08-02T19:10:34.267 に答える