問題タブ [mailboxprocessor]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net - TcpClient WriteAsync と ReadAsync を MailboxProcessor にラップする価値はありますか?
質問の要約:
- Stream.WriteAsync と Stream.ReadAsync は互いにブロックせず、2 つの CPU コアで完全に並列に実行できますか?
- 外部ソースが async{} で通知するのを待つことを通知する方法はありますか?
- TcpClient のラッパーとしての MailboxProcessor のパフォーマンスへの影響は何ですか?
いくつかの説明:
Stream.cs非同期操作のソースコードから理解できるように、完全に並列ではなく同期的に行われます(何かを読み取ると、他の読み取り試行が完了するまでブロックされ、書き込み試行もブロックされます。他の方法と同じです-書き込みブロックの読み取りと書き込みの試行) 、 writeAsync/readAsync を呼び出すスレッドをブロックしないという唯一の利点
だから私は TcpClient を受け入れる MailboxProcessor にラップしました
その目的は、接続が失敗した場合にクライアントを再接続することでした。この間、何も読み書きを試みたくありません。これは、スレッド同期手法でも可能ですが、より多くのコードが必要になります。
ソリューションのベンチマークを実行できる時期を特定できませんでしたが、MailboxProcessor 内部のベンチマークで、tcp 接続にどのような影響があるかを確認できますか (要求/応答時間全体に関してパフォーマンスへの影響が小さい場合)。
また、これは、応答の順序が受信した要求と同じであることを保証する要求をサーバーに送信するために作成されますが、信頼することはできませんWrite requestA
->Read responseA
正しい応答を読み取ることはできません。
キュー: ['write requestA'; '書き込みリクエスト B'; 'responseB を読む'; 'read responseA'] そして、これにより、responseA がスレッド 2 に返され、responseB がスレッド 1 に返されます。
リクエストに設定されたIDによってリクエストとレスポンスが関連付けられるのは良いことです。そのため、このプロトコルには を保存するソリューションがいくつかありますDictionary<id, TaskCompletionSource>
。これにより、Task が終了するまで待機し (TaskCompletionSource が結果を設定)、結果に進むことができます。結果は、TCP ストリームから応答を読み取り、ID でマッピングし続ける個別の単一スレッドによって設定されます。
F# では、Task の代わりに Async を使用するのが非常に美しいので、応答を正しい要求にマップする方法を確認する方法は、保存するDictionary<id, response -> unit>
ことSend request
です。
TaskCompletionSource に似た他の方法がありますが、Async の場合は次のようになります。
multithreading - Reply-channel で MailboxProcessor を使用して、順番に値を返す制限付きエージェントを作成します
私の状況では、計算のリストが大きすぎてスレッドが多すぎて生成されるため、基本的に、以下を制限されたスレッドソリューションに変更したいと考えています。より少ないスレッドでパフォーマンスを実験して測定したいと考えています。
私の新しいアプローチであるこのコードは、Tomas Petricek からのこのオンライン スニペットから借用/着想を得ています(私がテストしたところ、動作しますが、単位ではなく値を返す必要があります)。
これで、元のコードは次のようになります。
全体として、出力は正しい (応答を計算して伝搬する) が、(限られたセットの) スレッドでは正しくない。
私は少し遊んでいましたが、明らかなことを見逃していると思います (さらに、誰かが、計算を順番に返す制限されたスレッドのメールボックス プロセッサのアイデアを好むかもしれません)。
c# - F# はメールボックスプロセッサに似ていますが、複数のコンシューマがあります
F# または C# で、複数のコンシューマーによる受信メッセージの同時処理と、複数のプロデューサーへの応答の生成を可能にするプロデューサー/コンシューマー通信メカニズムを探しています。System.Collections.Concurrent.BlockingCollection は悪くありませんが、F# メールボックス プロセッサのようなメッセージ指向ではありません。メッセージ ベースの抽象化 (要求/応答ベース) が非常に望ましいです。F# のメールボックス プロセッサの変更可能な状態とは異なり、その内部は必須ではありません。メールボックス (メッセージ キュー) からの読み取りがブロックされる場合は、スレッドを F# のようにスレッド プールに解放する必要があります。スロットル (プロデューサを遅くするためのフロー制御) は理想的ですが、必須ではありません。何か案は?
f# - 複数の再帰非同期ボディを持つ F# エージェントは、それぞれに複数の inbox.Receive() を使用できますか?
ここに複数状態の F# MailboxProcessor の例がありますが、なぜそれがコンパイルされるのか疑問に思っていますが、動作は予期しないものです。「Expert F# 3.0」ページ 284 で提供されている一般的な例のパターンに従おうとしています。ここでは、複数の async {} ボディを使用すると複数の状態が許可されますが、inbox.Receive() を使用できるかどうかについては具体的ではありません。各非同期で?
収量
だからさせて!ループ 1 の msg = inbox.Receive() はスキップされますか? loop2 は return で完了すると思っていたでしょう。loop1 とそれをさせてください!inbox.Receive() の割り当ては、それが使用された非同期ブロックに固有です。