6

我已经看到不同的片段展示了Put一条返回unitF# 的消息MailboxProcessor。在某些情况下,仅Post使用该方法,而在其他情况下使用PostAndAsyncReply,一旦消息被处理,回复通道会立即回复。在做一些测试时,我发现等待回复的时间很长,所以除非你需要真正的回复,否则你应该使用Post.

注意:我开始在另一个线程中提出这个问题,但认为将其作为一个完整的问题发布很有用。在另一个线程中,Tomas Petricek 提到回复通道可以使用等待机制来确保调用者延迟到Put消息被处理。

是在消息排序方面使用PostAndAsyncReply帮助,还是只是在处理第一条消息之前强制暂停?在性能方面Post出现了正确的解决方案。那准确吗?

更新:

我只是想到了示例PostAndAsyncReply中可能需要的原因:用于在队列已满时查找消息,因此您不希望在前一个完成之前再查找消息。BlockingQueueAgentScanGetPutGetPut

4

2 回答 2

4

PostAndAsyncReply我想我一般同意你的总结 -比 慢是有道理的Post,所以如果调用者在操作(例如将值放入队列)完成时不需要从代理获得通知,它肯定应该公开一种使用 just 的方法Post。慢得多的事实PostAndAsyncReply可能意味着一些代理应该公开这两个选项并让调用者决定。

关于具体的例子BlockingQueueAgent(或者我以前实现one-place buffer的一个类似的例子),agent的典型应用就是解决consumer-producer问题。在消费者-生产者问题中,我们想在队列满时阻塞生产者,当队列为空时阻塞消费者。.NETBlockingCollection只支持同步阻塞,这有点糟糕(即它可以阻塞整个线程池)。

使用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. 使用队列的阻塞(读取和写入时)控制并行度,使管道的步骤并行运行,但如果管道不能以所需的速度处理图像,它不会继续加载越来越多的图像。

于 2011-12-15T22:08:04.820 回答
4

我的建议是设计您的系统,以便您可以Post尽可能多地使用。

该技术专为异步并发而设计,其目标是即发即弃消息。等待响应的想法直接违背了这一点。

于 2013-07-01T09:53:46.037 回答