[英]Use Post or PostAndAsyncReply with F#'s MailboxProcessor?
我已經看到了不同的片段展示了一個Put
返回消息unit
與F#的MailboxProcessor
。 在某些情況下,只使用Post
方法,而其他人使用PostAndAsyncReply
,一旦處理消息,回復通道立即回復。 在做一些測試時,我發現在等待回復時有很長的時間滯后,所以看起來除非你需要真正的回復,否則你應該使用Post
。
注意:我開始在另一個帖子中詢問這個問題,但認為發布完整問題很有用。 在另一個帖子中,Tomas Petricek提到回復通道可以使用等待機制來確保調用者延遲直到Put
消息被處理。
使用PostAndAsyncReply
是否有助於消息排序,還是只是強制暫停直到處理第一條消息? 在性能方面, Post
出現了正確的解決方案。 那是准確的嗎?
更新:
我剛剛想到了為什么在BlockingQueueAgent
示例中可能需要PostAndAsyncReply
的原因:當隊列已滿時, Scan
用於查找Get
消息,因此您不希望在前一個Put
完成之前先Put
然后Get
。
我的建議是設計你的系統,這樣你就可以盡可能地使用Post
。
該技術專為異步並發而設計,其目標是發送即發消息。 等待回應的想法直接違背了這一點。
我認為我通常同意你的摘要 - PostAndAsyncReply
比Post
慢,所以如果調用者在操作(例如將值放入隊列)完成時不需要從代理獲得通知,那么它應該是肯定會使用Post
一種方法。 PostAndAsyncReply
慢得多的事實可能意味着某些代理應公開這兩個選項並讓調用者決定。
關於BlockingQueueAgent
(或者我用來實現單位緩沖區的類似例子)的具體示例,代理的典型應用是解決消費者 - 生產者問題。 在消費者 - 生產者問題中,我們希望在隊列滿時阻止生產者,並在消費者為空時阻止消費者。 .NET BlockingCollection
僅支持同步阻塞,這有點不好(即它可以阻塞整個線程池)。
在使用BlockingQueueAgent
發送該Put
使用訊息話題PostAndAsyncReply
,我們可以等到元素被添加到隊列異步(所以它會阻止生產國,但不阻塞線程!)典型應用的一個例子是圖像處理流水線 ,我寫的前一段時間。 這是一個片段:
// 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
。 使用隊列的阻塞(在讀取和寫入時)都控制並行性,因此管道的步驟並行運行,但如果管道無法以所需的速度處理它們,則不會繼續加載越來越多的圖像。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.