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行う必要はありません。