問題タブ [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.
f# - リモートのMailboxProcessors間でメッセージを渡しますか?
私はMailboxProcessor
、独自のことを行う個別のエージェントを維持するためにクラスを使用しています。通常、エージェントは同じプロセスで相互に通信できますが、エージェントが別々のプロセスまたは異なるマシン上にある場合でも、エージェントが相互に通信できるようにしたいと思います。それらの間の通信を実装するには、どのようなメカニズムが最適ですか?標準的な解決策はありますか?
私はUbuntuインスタンスを使用してエージェントを実行していることに注意してください。
concurrency - F# で TryScan を適切に使用する方法
の使い方の例を見つけようとしTryScan
ましたが、何も見つかりませんでした。
私がやりたいこと (非常に単純化された例): MailboxProcessor
2 種類のメッセージを受け入れる があります。
最初のもの
GetState
は現在の状態を返します。GetState
メッセージはかなり頻繁に送信されますもう 1 つ
UpdateState
は非常にコストがかかります (時間がかかります)。たとえば、インターネットから何かをダウンロードし、それに応じて状態を更新します。UpdateState
めったに呼び出されません。
私の問題は-メッセージGetState
がブロックされ、前のメッセージが提供されるまで待機することUpdateState
です。そのため、TryScan
すべてのGetState
メッセージを処理するために使用しようとしましたが、うまくいきませんでした。
私のコード例:
コードを実行しようとするとGetState
、結果を待っているため、メッセージがほとんど処理されていないことがわかります。一方、UpdateState
発火して忘れるだけなので、状態の取得を効果的にブロックします。
編集
私のために働く現在の解決策はこれです:
コメントへの反応: otherMailboxProcessor
またはThreadPool
を並列に実行するアイデアUpdateState
は素晴らしいですが、現在は必要ありません。私がやりたかったのは、すべてのGetState
メッセージを処理し、その後で他のメッセージを処理することだけです。処理中UpdateState
にエージェントがブロックされてもかまいません。
出力の問題が何であったかを示します。
f# - この F# コードを MailboxProcessor と共に使用すると、期待される出力が生成されないのはなぜですか?
私は Don Syme のブログ記事Async and Parallel Design Patterns in F#: Agentsの 1 つを読んでいました。ただし、次の一見非常に単純なコードでは、期待どおりの出力が生成されませんでした。
予想される 10,000 メッセージの代わりに、Ubuntu で Mono 2.8.1 を使用して約 3000 メッセージ、または Windows XP で Visual F# を使用して 15 メッセージしか受け取りませんでした。ここで何か不足していますか?ところで、printfn ステートメントを次の File op に置き換えようとしたところ、同じ部分的な結果になりました。
multithreading - F# MailboxProcessor に関する質問
http://fssnip.net/3Kのコードを使用してコンソール プログラムを作成しました。そして、私はそれを見つけました
最後に「System.Console.ReadLine() |> ignore」を追加して、スレッドの終了を待ちます。すべての MailBoxProcessors が完了し、プログラムが終了できることを確認できますか?
テストURL「www.google.com」を無効なURLに変更しようとしたところ、次の出力が得られました。「出力競争」を回避することはできますか?
[編集]
Tomas の更新http://fssnip.net/65を使用した後も、最後の出力/クロールは終了します。以下は、「制限」を 5 に変更し、デバッグ メッセージを追加した後のプログラムの出力です。最後の行は、短縮された URL を示しています。すべてのクローラーが実行を終了したかどうかを検出する方法はありますか?
メインコードを次のように変更しました
ただし、最後に Console.Readline() を追加しない限り、最後のprintfn "[Main] after crawl"は実行されません。
[編集2]
コードは fsi の下で問題なく動作します。ただし、 fsi --use:Program.fs --exec --quiet を使用して実行した場合、同じ問題が発生します。
multithreading - コンパイルされたコンソール コマンドライン プログラムがすべてのスレッドの終了を待たない
コードがコンソール プログラムにコンパイルされるか、 fsi --use:Program.fs --exec --quietとして実行される場合、一部のスレッドは終了する前に終了します。すべてのスレッドが終了するのを待つ方法はありますか?
この問題は、「複数の MailboxProcesser が存在する場合のプログラム終了の問題」として説明できます。
出力例
(最後の行が切り捨てられ、最後の出力関数 ( printfn "[Main] after crawl"
) が実行されないことに注意してください。)
コード
編集:いくつか追加しましSystem.Threading.Thread.CurrentThread.IsBackground <- false
た。
concurrency - F# の MailboxProcessor で Post または PostAndAsyncReply を使用しますか?
F#Put
で返されるメッセージを示すさまざまなスニペットを見てきました。メソッドのみを使用するものもあれば、 を使用するものもあり、メッセージが処理されるとすぐに応答チャネルが応答します。いくつかのテストを行ったところ、返信を待っているときにかなりのタイムラグがあることがわかったので、本当の返信が必要でない限り、を使用する必要があるようです.unit
MailboxProcessor
Post
PostAndAsyncReply
Post
注:別のスレッドでこれを尋ね始めましたが、完全な質問として投稿すると便利だと思いました. 別のスレッドで、Tomas Petricek は、応答チャネルを待機メカニズムとして使用して、Put
メッセージが処理されるまで呼び出し元を遅らせることができると述べました。
メッセージの順序付けに役立ちますかPostAndAsyncReply
、それとも最初のメッセージが処理されるまで強制的に一時停止するだけですか? パフォーマンスに関してはPost
、適切なソリューションのようです。それは正確ですか?
アップデート:
例PostAndAsyncReply
で必要になる理由を考えただけです:キューがいっぱいのときにメッセージを見つけるために使用されるため、前のメッセージが完了する前にメッセージを検索したくありません。BlockingQueueAgent
Scan
Get
Put
Get
Put
memory-leaks - Microsoft.FSharp.Control.Mailbox でのメモリ リーク?
現在、長時間実行されているサービス (F# を使用) でいくつかのメモリ リークを探しています。これまでに見た唯一の「奇妙な」ものは次のとおりです。
- QueueChannelCommands という名前の代数データ型を持つサブシステムで MailboxProcessor を使用します (多かれ少なかれ一連の Add/Get コマンド - AsyncReplyChannels が添付されたものもあります)
- (Ants Memory Profiler を使用して) サービスをプロファイリングすると、言及されたタイプの配列のインスタンスが表示されます (ほとんどの長さは 4 ですが、成長しています) - Control.Mailbox によって参照が保持されているように見えるすべての空 (null):
私のコードには、この動作の理由がわかりません (標準コードは、そこにあるすべての Mailbox-example で見つけることができlet! = receive
ますmatch
。return! loop()
誰もこの種の動作を見たことがありますか、またはこれを処理する方法を知っていますか? それとも、これは (既知の) バグですか?
更新:配列の成長は本当に奇妙です-適切に使用されていない追加のスペースが追加されているようです:
f# - MailboxProcessor.PostAndReplyデザインの選択
見つめている:
署名が私にとって直感に反しているように見える理由がわかりません。私たちがやりたいのは、エージェントにメッセージを投稿し、返信を待つことです。なぜ私たちは彼に「メッセージ」として奇妙な機能を与えなければならないのですか?
このMSDNスニペットをもう一度参照してください。
私はむしろこのようなものを好みます:
ありがとう
asynchronous - Async.TryCancelled は Async.RunSynchronously では機能しません
ユーザーの操作に基づいて UI を更新するエージェントを作成しようとしています。ユーザーがボタンをクリックすると、GUI が更新されます。モデルの準備には時間がかかるため、ユーザーが他のボタンをクリックすると、準備がキャンセルされ、新しいモデルが開始されることが望ましいです。
私がこれまでに持っているもの:
CancellationTokenSource
リクエストごとに a を返し、それを可変変数に格納します (x.Refresh() はスレッド セーフであり、UI スレッドで呼び出されます)。初めて Refresh() を呼び出すと、キャンセル元が返されます。Refresh() が 2 回目に呼び出された場合は、Async.RunSynchronously で実行する非同期タスクを中止する Cancel を呼び出します。
ただし、例外が発生します。私のサンプルからの出力は
これについて考えると、エージェントが実行されているスレッドが中断されたので、それは理にかなっているかもしれませんよね? しかし、どうすれば望ましい動作を実現できますか?
エージェントが新しいメッセージを引き続き使用できるように、エージェント内の非同期ワークフローをキャンセルする必要があります。なぜメールボックス プロセッサを使用するのですか? 1 つのスレッドだけが UI モデルを作成しようとしていることが保証されているため、リソースを節約できます。
いくつかの Web サービスからデータをダウンロードして UI モデルを作成するとします。そのため、非同期呼び出しを使用します。ユーザーがコンボを変更して他のオプションを選択すると、古い値で Web サービスのクエリを停止 (= 非同期呼び出しをキャンセル) し、新しい値で Web サービス呼び出しの新しいモデル ベースを作成したいと考えています。
私のソリューションの代わりに使用でき、私の問題を解決する提案も大歓迎です。