6

F#Putで返されるメッセージを示すさまざまなスニペットを見てきました。メソッドのみを使用するものもあれば、 を使用するものもあり、メッセージが処理されるとすぐに応答チャネルが応答します。いくつかのテストを行ったところ、返信を待っているときにかなりのタイムラグがあることがわかったので、本当の返信が必要でない限り、を使用する必要があるようです.unitMailboxProcessorPostPostAndAsyncReplyPost

注:別のスレッドでこれを尋ね始めましたが、完全な質問として投稿すると便利だと思いました. 別のスレッドで、Tomas Petricek は、応答チャネルを待機メカニズムとして使用して、Putメッセージが処理されるまで呼び出し元を遅らせることができると述べました。

メッセージの順序付けに役立ちますかPostAndAsyncReply、それとも最初のメッセージが処理されるまで強制的に一時停止するだけですか? パフォーマンスに関してはPost、適切なソリューションのようです。それは正確ですか?

アップデート:

PostAndAsyncReplyで必要になる理由を考えただけです:キューがいっぱいのときにメッセージを見つけるために使用されるため、前のメッセージが完了する前にメッセージを検索したくありません。BlockingQueueAgentScanGetPutGetPut

4

2 に答える 2

4

私は一般的にあなたの要約に同意すると思います-PostAndAsyncReplyより遅いのは理にかなっていますPost。したがって、操作(値をキューに入れるなど)が完了したときに発信者がエージェントから通知を受け取る必要がない場合は、間違いなく公開する必要がありますだけを使用してそれを行う方法PostPostAndAsyncReplyはるかに遅いという事実は、おそらく、一部のエージェントが両方のオプションを公開し、発信者に決定させる必要があることを意味します.

の特定の例BlockingQueueAgent(または 1 プレース バッファーを実装するために使用した同様のもの) に関して、エージェントの典型的なアプリケーションは、消費者と生産者の問題を解決することです。コンシューマーとプロデューサーの問題では、キューがいっぱいのときにプロデューサーをブロックし、キューが空のときにコンシューマーをブロックしたいと考えています。.NETBlockingCollectionは同期ブロッキングのみをサポートしますが、これは少し悪いことです (つまり、スレッド プール全体をブロックする可能性があります)。

を使用してメッセージをBlockingQueueAgent送信するを使用すると、要素が非同期的にキューに追加されるまで待機できます (したがって、プロデューサーをブロックしますが、スレッドをブロックすることはありません!) 典型的な使用例は、私が少し前に書いた画像処理パイプラインです。 . その中の 1 つのスニペットを次に示します。PutPostAndAsyncReply

// Phase 2: Scale to a thumbnail size and add frame
let scalePipelinedImages = async {
   while true do 
     let! info = loadedImages.AsyncGet()
     scaleImage info
     do! scaledImages.AsyncAdd(info) }

このループは繰り返しloadedImagesキューから画像を取得し、何らかの処理を行い、結果を に書き込みますscaledImages。キューを使用したブロック (読み取り時と書き込み時の両方) によって並列性が制御されるため、パイプラインのステップが並列に実行されますが、パイプラインが必要な速度で処理できない場合、ますます多くのイメージをロードし続けることはありません。

于 2011-12-15T22:08:04.820 に答える