6

ネットワークアプリケーションプロトコル用のクライアントライブラリを開発しています。

クライアントコードはライブラリを呼び出してライブラリを初期化し、サーバーに接続します。クライアントはもちろんサーバーにリクエストを送信できますが、サーバーはクライアントにリクエスト(コマンド、以下ではCmdと呼びます)を送信することもできます。

トランスポートプロトコルはTCP/IPであるため、基本的にクライアントライブラリはサーバーに接続し、非同期メソッドを呼び出してサーバーから次の要求または応答を取得し、からの応答/要求を待機している間のI/Oブロッキングを回避します。サーバー。

そうは言っても、クライアントがサーバーからの要求を受信できるようにするために、ライブラリに2つの可能な解決策(C#構造のみを使用し、特定のサードパーティフレームワークを使用しない)があります。

図書館で次のようなイベントを提供する

public EventHandler<ReceivedCmdEventArgs> event ReceivedCmd;

サーバーから着信するリクエストの通知を受け取るために、クライアントがサブスクライブすること。もちろん、このメカニズムでは、サーバーからリクエストを受信し、Cmd受信でイベントを発生させるために、クライアントライブラリで非同期ループを作成する必要があります。

または、他の解決策は、クライアントライブラリでそのようなメソッドを作成することです

public async Task<Cmd> GetNextCmdAsync()

クライアントコードが非同期ループを呼び出してコマンドを受信すること。

これらのソリューションは同じようなものですか?C#5のasync / await constrcutsを完全に使用し、イベントに依存しない方がよいでしょうか?違いは何ですか?何かお勧め、コメント?

ありがとう !

4

3 に答える 3

4

Task単一のコマンドの受信など、単一の非同期アクションを表します。そのため、イベントのストリームには直接適していません

イベントのストリームの究極のライブラリはReactiveExtensions(Rx)ですが、残念ながら、かなり急な学習曲線があります。

新しいオプションは、あまり知られていないTPL Dataflowです。これにより、async使いやすいデータフローメッシュを構築できます。実際、私はasync使いやすいTCP / IPソケットラッパーを作成ISourceBlock<ArraySegment<byte>>しており、読み取りストリームとして公開しています。エンドユーザーは、そのブロックから直接受信するか(ReceiveAsync)、またはブロックを独自のデータフローに「リンク」することができます(たとえば、メッセージのフレーミング、解析、さらには処理を行うことができます)。

データフローはRxよりもわずかに効率が低くなりますが、学習曲線を低くするだけの価値があると思います。

ベアイベントはお勧めしません-フリースレッドイベント(ソケットクロージャーの処理方法を考えてください-廃棄後にイベントが発生する可能性がありますか?)またはイベントベースの非同期パターン(独自の同様の問題があります)のいずれかになります提供されたものに同期しますSynchronizationContext)。RxとDataflowはどちらも、同期と廃棄/サブスクリプション解除のためのより優れたソリューションを提供します。

于 2012-08-20T12:37:06.563 に答える
3

あなたの場合は、イベント駆動型のアプローチの方が優れていると思います。

実際、あなたはオブザーバブル/オブザーバーパターンについて話しているのです。不明な数のリスナー/オブザーバーが、何らかのコマンドを受信した場合に何かを実行するのを待っています。

非同期/待機パターンは、イベント駆動型のアプローチと同様に機能しません。これは、コマンドを受信したことを報告するたびに、私が望むことを実行するのとは逆に、1つの結果を期待するようなものになるためです。

概念的に言えば、私はイベント駆動型のアプローチを好みます。それは、アーキテクチャの目標によりよく適合するからです。

C#5の非同期/待機パターンはあなたのケースに合わせて設計されていませんが、一部のコードが非同期タスクを実行し、タスクが結果を受け取った後に次のコード行を実行する必要がある場合に使用します。

于 2012-08-20T10:53:01.890 に答える
0

ライブラリを作成しているので、イベントの方が適しているようです。

イベントを使用すると、コールバックを指定する必要がなくてもライブラリを構築できます。

あなたの図書館の消費者は彼らが何に興味を持っているかを決定し、それらのイベントに耳を傾けます。

一方、非同期タスクは、遅延(IO、ネットワークなど)が発生することがわかっている場合に使用されます。非同期タスクを使用すると、これらの遅延が発生している間にリソースを解放できるため、リソースの使用率が向上します。

非同期タスクは、発生したイベントの代わりにはなりません。

于 2012-08-20T10:52:12.150 に答える