14

the new async/await keywords in C# 5 look very promising but I read an article about the performance impact on those applications since the compiler will generate a quite complex state machine for async methods.

Async-programming using these keywords is so much easier but is it as good as say SocketAsyncEventArgs for Sockets ?

Second question: Are asynchronous IO methods like Stream.WriteAsync really asynchronous (Completion Ports on .Net or epoll/poll on Mono) or are these methods cheap wrappers for pushing a write call to a threadpool ?

Third question: Beside the SynchronizationContext of an UI application, is there a way to implement some kind of sinlge-threaded context ? Something like an event loop so that finished tasks continues on the main thread ? I discovered the Nito.AsyncEx library, but I'm not quite sure whether or not this is what i need.

4

2 に答える 2

32

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

于 2013-02-07T00:33:39.650 に答える
6
  1. 非同期IOのコンテキストで使用している場合、それは重要なポイントです。データベース操作、ファイル/ネットワークIOなどに費やされる時間は、せいぜいミリ秒です。のオーバーヘッドはasync、ナノ秒がないとしても、最悪の場合マイクロ秒になります。注意が必要なのは、待機している操作が多数あり(数千、数万、またはそれ以上など)、それらの操作が非常に高速な場合です。これらの非同期操作がCPUにバインドされた作業を表す場合、使用のオーバーヘッドがawait少なくとも目立つ可能性があります。ステートマシン用に生成されたコードは、人間の理解しやすさの点でやや複雑ですが、ステートマシンは一般に、全体としてかなりうまく機能する傾向があることに注意してください。

  2. メソッドは、スレッドプールスレッドをブロックする単なるラッパーではありません。awaitそれは何を表すかの目的を打ち負かすでしょう。これらのメソッドはスレッドをブロックせずタスクを完了するためにOSフックに依存します。

  3. もちろん、SynchronizationContextUIフレームワークによって提供される既存のものに完全に依存する代わりに、独自のものを作成することができます。 これが良い例です。このようなものを使用するときは注意してください。これは適切なタスクに適したツールですが、すべてを非同期で実行する必要がある場合に、悪用してブロックのより作成的な方法を見つけることができます。

于 2013-02-06T22:16:57.510 に答える