1

HTTP 応答を完全に非同期(async/await を使用)に実装しようとしています。

これは非常に単純化されていますが、作成する必要がある小さな書き込みが複数あると仮定しましょう。

for (int i=0; i<1000; i++) WriteToResponse(words[i]);

たとえば、オブジェクトを JSON または XML に手動でエンコードし、オブジェクトのトラバーサル中に遭遇したときに各オブジェクトを応答に書き込むというユース ケースがあります。

私の現在の実装は次のとおりです。

async Task Respond(HttpResponse res)
{
    for (int i=0; i<1000; i++) await res.Output.WriteAsync(words[i]);
}

これはこれを行う正しい方法ですか?

ここですべての非同期性が多くのオーバーヘッドを追加しているのではないかと少し心配しています。書き込もうとしているすべての単語に対してバックグラウンドでコールバックをスケジュールしている場合、全体を同期的に書き出す必要がありますか?

同期の時代に戻ったとき、バッファリングがどのように機能するかを理解していました。出力ストリームに書き込んだところ、実際にはバックグラウンドでバッファリングされていました。バッファーが十分にいっぱいになると、フラッシュされ、実際に同期的にソケットに書き込まれます。しかし、非同期で作業する場合、これはどのように機能するのでしょうか? まだバッファリングされていますか?それとも、次の書き込みを行う前に、すべての小さな書き込みの完了を実際に待っているのでしょうか?

4

1 に答える 1

4

バッファリングは同期性とは無関係であると予想されます-したがって、バッファリング中、「非同期」書き込みは実際には同期的に完了する可能性が高く(メモリ内にあるため)、その時点でawait.

バッファーが十分に大きくなると、ソケットへの書き込みが開始され、その時点で、余分な (小さな) ヒットでawait実際に非同期になります。

ただし、単語を結合してから単一の書き込みを実行するだけで、コードを単純にすることをお勧めします。結局のところ、あなたはすでにすべてのデータを持っています。その一部を待っているわけではありません。

その時点で、非同期呼び出しは 1 つしかないため、以下を使用する必要さえありませんawait

Task Respond(HttpResponse res)
{
    string data = string.Join("", words.Take(1000)); // Or whatever
    return res.Output.WriteAsync(data);
}
于 2013-08-15T09:55:38.350 に答える