9

async/await が理にかなっている場所 (IO Completion Ports を解放してスレッド スタベーションを回避するためなど) と作業単位が単純すぎて実行できない/安すぎるため、同期実行はより良い選択。

言い換えれば、async/await を使用すると、比較的高速でリソースが安価な作業単位と組み合わせて使用​​するとパフォーマンスが低下する可能性があり、単純に作業を同期的に実行することが推奨されるアプローチでしょうか?

例 (すべて 1 つのメソッドで、すべて await で非同期):

  • いくつかのマイナー アップデートを DB に保存する
  • を使用してストリームにアップロードされた非常に小さなファイルを読み取るReadAsStreamAsync
  • を使用して読み取りストリームをファイル ストリームにコピーします。CopyToAsync
  • を使用して書き込みストリームをフラッシュしていますFlushAsync
4

2 に答える 2

11

これは、タイミングの観点からではなく、I/O 対 CPU の観点からアプローチすることをお勧めします。

CPU バウンドのメソッドは当然同期的です。I/O バウンド メソッドは、本来、非同期です。

あなたの例に基づいて、あなたの環境はサーバー側であると想定しています:

  • いくつかのマイナー アップデートを DB に保存します。必然的に非同期: ネットワーク (または少なくともプロセス外) 通信、競合の可能性、ディスク I/O。
  • ReadAsStreamAsync を使用して、ストリームにアップロードされた非常に小さなファイルを読み取ります。当然のことながら非同期: ネットワーク通信。
  • CopyToAsync を使用して読み取りストリームをファイル ストリームにコピーします。当然のことながら非同期: 競合、ディスク I/O の可能性。
  • FlushAsync を使用したライター ストリームのフラッシュ。当然のことながら非同期: 競合、ディスク I/O の可能性。

これらはすべて非同期操作であるため、すべて非同期で実装する必要があります。CPU はメモリよりも非常に高速であり、メモリはネットワークやディスク I/O よりも非常に高速です。このため、当然のことながら非同期メソッドを同期的に実装すると、スレッドがブロックされます。これは世界の終わりではありませんが、スレッドプールが長時間ブロックされている場合はそれを補う必要があり、「節約」している唯一の時間はスレッド切り替え時間であり、これはどのネットワークよりも桁違いに短くなります。またはディスク I/O が可能性があります

考慮すべきもう 1 つのことは、通常、リソースの競合が原因で発生する、予測できないレイテンシです。別のプロセスが同時にデータベースに書き込みを行っている場合はどうなりますか? ファイルのアップロード中にルーティングの問題が発生し、パケットの再送信が必要になった場合はどうなりますか? 出力ファイルを書き込もうとしているときにディスクが最適化されている場合はどうなりますか? 非同期操作は、このように予測不能になる傾向があり、asyncコードによって、予想よりもはるかに長くスレッドをブロックしないことが保証されます。

結論として、同期 (CPU バウンド) 作業には同期コードを使用し、非同期 (I/O バウンド) 作業には非同期コードを使用します。

于 2013-10-31T11:13:42.743 に答える