You can asynchronously return a value for each processed message if you send an AsyncReplyChannel<'a>
as part of the message.
type MessageWithResponse = Message of InputData * AsyncReplyChannel<OutputData>
Then the mailbox processor can use this channel when processing the message to send a value back to the caller.
let! message = inbox.Receive()
match message with
| MessageWithResponse (data, r) ->
// ...process the data
let output = ...
r.Reply(output)
Now to create a message, you need the AsyncReplyChannel<'a>
- what is is and how do you create a working instance? The best way is to let MailboxProcessor provide it for you and extract the response to a more common Async<'a>
. This can be done by using for example the PostAndAsynReply
method, where you don't post the complete message, but instead a function of type (in our case) AsyncReplyChannel<OutputData> -> MessageWithResponse
:
let! output = processor.PostAndAsyncReply(r -> MessageWithResponse(input, r))
This will post the message in a queue and await the reply, which will arrive once the processor gets to this message and replies using the channel.
There is also a synchronous variant PostAndReply
which blocks the calling thread until the processor replies.