私は、中央サーバーへの通信に raw TCP ソケットを使用するクライアント アプリケーションに取り組んでいます。アプリケーション メッセージはシリアル化され、TCP ストリームに渡されるフレームを作成するために長さがプレフィックスされます。
これを処理するための古典的な方法の 1 つは、ソケット クラスで Receive または BeginReceive を直接呼び出し、コールバックでメッセージを逆シリアル化し、メッセージを別のスレッドで処理するために別のキューに渡し、コールバックにソケットで別の受信を再度開始させることです。
このアプローチの素朴な実装は私にとって理想的ではありません.メッセージのシリアライゼーションとデシリアライゼーションをソケットに密接に結合し、キューが異なるスレッド/コールバックでうまく機能するようにするにはかなりの「配管」が必要です. また、これはやや漏れやすい抽象化でもあります。呼び出し元のコードには、入力メッセージと出力メッセージの「データ フロー」ではなく、基礎となるソケットの知識が必要です。
完全に .NET 4.5 内で作業していることを考えると、TPL (TaskFactory.FromAsync) を使用してソケットの Begin および End 非同期メソッドをラップすることは当然の選択です。ただし、いくつかの理由により、この時点からどのように進めればよいかわかりません。
- データを受信するために完了しない非同期の「タスク」が必要です。ソケットが接続されている限り、メッセージのストリームを処理したいと思います。中断 (切断、ソケット エラー、またはキャンセル要求) は、従来のタスクの完了ではなく、例外になります。Stephen Toub ( http://blogs.msdn.com/b/pfxteam/archive/2011/10/02/10218999.aspx ) によると、私は常にタスクを完了する必要があります。これにより、少し問題が生じます。従来の意味では、ソケットの受信は決して完了しません。Stephen は、「Awaiting Socket Operations」の投稿で少し矛盾しているように見えます。そこでは、ソケット エラーなしでは決して完了しないソケット読み取りを示しています ( http://blogs.msdn.com/b/pfxteam/archive/2011/12/15 /10248293.aspx )。
- 送信するデータを同期的に「キューに入れる」方法が必要です。発信者は、送信されるメッセージをブロックせずに送信できる必要があり、メッセージはソケットを介して順次送信される必要があります。つまり、メッセージのフレーミングにより、ソケット自体で一度に 1 つの送信のみが行われます。TPL データフローは適していますか、それとも別のキューイング パターンを使用する必要がありますか?
- メッセージのシリアル化とメッセージの送信の間の懸念を明確に分離したいと思います。
このタイプの戦略の例はあまり見たことがなく、「直接的な」ソケット I/O または単純な実装のみです。私の直感では、シリアライゼーションとデシリアライゼーションをパイプライン処理できることを考えると、TPL Dataflow が適していることがわかります。
Receive タスクの効果的に無限のチェーンを TPL Dataflow などに橋渡しする方法がわかりません。
何か案は?