async
それ自体は非常にパフォーマンスが高いです。たくさんの仕事がこれに入りました。
async
一般に、サーバー側ではI/Oが心配です。とにかくノイズでオーバーヘッドが失われるasync
ので、CPUバウンドメソッドを無視します。async
非同期I/Oは、リクエストごとのメモリ使用量を増やしますが、リクエストごとのスレッド使用量を減らします。したがって、最終的に勝つことになります(境界性の病理学的コーナーケースを除く)。これは、を含むすべての非同期I/Oに当てはまりますasync
。
await
タイプだけでなくパターンを使用して設計されているTask
ため、可能な限り多くのパフォーマンスを引き出す必要がある場合は、それが可能です。
コンパイラーは非同期メソッド用の非常に複雑なステートマシンを生成するため、これらのアプリケーションのパフォーマンスへの影響に関する記事を読みました。
StephenToubが読んだ記事は素晴らしいです。Zen of Asyncビデオ(これもStephen Toubによる)もお勧めします。
これらのキーワードを使用した非同期プログラミングは非常に簡単ですが、SocketsのSocketAsyncEventArgsと同じくらい良いですか?
SocketAsyncEventArgs
まず、メモリの無駄を減らすため、よりスケーラブルであることを理解してください。ソケットを使用するより簡単な方法でasync
は、より多くのメモリガベージが生成されますが、await
パターンベースであるため、 API用に独自のasync
互換性のあるラッパーをSocketAsyncEventArgs
定義できます(Stephen Toubのブログで見られるように...ここでパターンを検出しています;)。これにより、1オンスのパフォーマンスをすべて引き出すことができます。
通常、長期的には、いくつかのメモリ割り当てを回避するためにコードをねじるよりも、スケールアウトシステムを設計する方が適切です。私見では。
2番目の質問:Stream.WriteAsyncのような非同期IOメソッドは本当に非同期ですか(.Netの完了ポートまたはMonoのepoll / poll)、またはこれらのメソッドはスレッドプールに書き込み呼び出しをプッシュするための安価なラッパーですか?
モノについてはわかりません。.NETでは、ほとんどの非同期I/Oメソッドは完了ポートに基づいています。クラスはStream
注目すべき例外です。基本クラスはStream
デフォルトで「安価なラッパー」を実行しますが、派生クラスがこの動作をオーバーライドできるようにします。Stream
ネットワーク通信からのsは常にこれをオーバーライドして、真に非同期のI/Oを提供します。Stream
ファイルを処理するsは、ストリームが非同期I / O用に明示的に構築された場合にのみ、これをオーバーライドします。
3番目の質問:UIアプリケーションのSynchronizationContextの他に、ある種のシングルスレッドコンテキストを実装する方法はありますか?
ASP.NETにもがありSynchronizationContext
ます。したがって、ASP.NETを使用している場合は、既に設定されています。
独自のソケットベースのサーバー(Win32サービスなど)を使用している場合は、AsyncExライブラリのタイプを使用できます。AsyncContext
しかし、これはあなたが実際に望んでいるものではないようです。AsyncContext
現在のスレッドにシングルスレッドのコンテキストを作成します。async
しかし、サーバーアプリケーションの真の力は、スレッドではなくリクエストのスケーリングにあります。
ASP.NETがどのように機能するかを検討してくださいSynchronizationContext
。各要求が着信すると、スレッドプールスレッドを取得し、SynchronizationContext
(その要求に対して)を構築します。そのリクエストに非同期の作業がある場合、リクエストはに登録され、SynchronizationContext
そのリクエストを実行しているスレッドはスレッドプールに戻ります。その後、非同期作業が完了すると、スレッドプールスレッド(任意のスレッド)を取得し、既存のスレッドをインストールしSynchronizationContext
て、その要求の処理を続行します。リクエストが最終的に完了すると、そのリクエストは破棄SynchronizationContext
されます。
そのプロセスの鍵は、要求がawait
非同期操作を待機しているとき()、その要求専用のスレッドがないことです。リクエストはスレッドに比べてかなり軽量であるため、これによりサーバーの拡張性が向上します。
SynchronizationContext
各リクエストにのようなシングルAsyncContext
スレッドを指定した場合、これは、何もすることがない場合でも、スレッドを各リクエストにバインドします。これは、同期マルチスレッドサーバーよりも優れているとは言えません。
独自の発明に取り組みたい場合は、 MSDNの記事がSynchronizationContext
役立つかもしれませんSynchronizationContext
。また、その記事では、非同期メソッドがコンテキストを「登録」および「インストール」する方法についても説明します。これはほとんど自動的に行われるため、明示的async void
にawait
行う必要はありません。