MailboxProcessor.PostAndAsyncReply<'Msg,'Reply> Method (F#)

Posts a message to an agent and await a reply on the channel, asynchronously.

Namespace/Module Path: Microsoft.FSharp.Control

Assembly: FSharp.Core (in FSharp.Core.dll)

// Signature:
member this.PostAndAsyncReply : (AsyncReplyChannel<'Reply> -> 'Msg) * ?int -> Async<'Reply>

// Usage:
mailboxProcessor.PostAndAsyncReply (buildMessage)
mailboxProcessor.PostAndAsyncReply (buildMessage, timeout = timeout)

Parameters

  • buildMessage
    Type: AsyncReplyChannel<'Reply> -> 'Msg

    The function to incorporate the AsyncReplyChannel into the message to be sent.

  • timeout
    Type: int

    An optional timeout parameter (in milliseconds) to wait for a reply message. The default is -1 which corresponds to Infinite().

Return Value

An asychronous computation (Async object) that will wait for the reply from the agent.

Remarks

The message is generated by applying buildMessage to a new reply channel to be incorporated into the message. The receiving agent must process this message and invoke the Reply method on this reply channel precisely once.

Example

The following code example shows a mailbox processor agent that uses PostAndAsyncReply. The return value of PostAndAsyncReply is an asynchronous workflow, which in this example is started by using Async.StartWithContinuations, to set up the code that handles the reply.

open System

type Message = string * AsyncReplyChannel<string>

let formatString = "Message number {0} was received. Message contents: {1}"

let agent = MailboxProcessor<Message>.Start(fun inbox ->
    let rec loop n =
        async {            
                let! (message, replyChannel) = inbox.Receive();
                // Delay so that the responses come in a different order.
                do! Async.Sleep( 5000 - 1000 * n);
                replyChannel.Reply(String.Format(formatString, n, message))
                do! loop (n + 1)
        }
    loop (0))

printfn "Mailbox Processor Test"
printfn "Type some text and press Enter to submit a message."

let isCompleted = false
while (not isCompleted) do
    printf "> "
    let input = Console.ReadLine()
    let messageAsync = agent.PostAndAsyncReply(fun replyChannel -> input, replyChannel)

    // Set up a continuation function (the first argument below) that prints the reply.
    // The second argument is the exception continuation (not used).
    // The third argument is the cancellation continuation (not used).
    Async.StartWithContinuations(messageAsync, 
         (fun reply -> printfn "%s" reply),
         (fun _ -> ()),
         (fun _ -> ()))

printfn "Press Enter to continue."
Console.ReadLine() |> ignore

Following is an example session. The output might be interleaved, which shows that the message processing function is running on multiple threads.

Mailbox Processor Test
Type some text and press Enter to submit a message.
> hello
> hello?
> testing
> testing Message number 0 was received. Message contents: hello
1
> testing2
> Message number 1 was received. Message contents: hello?
testing3
> Message number 2 was received. Message contents: testing
Message number 3 was received. Message contents: testing 1
MeMessage number 5 was received. Message contents: testing3
ssage number 4 was received. Message contents: testing2

Platforms

Windows 7, Windows Vista SP2, Windows XP SP3, Windows XP x64 SP2, Windows Server 2008 R2, Windows Server 2008 SP2, Windows Server 2003 SP2

Version Information

F# Runtime

Supported in: 2.0, 4.0

Silverlight

Supported in: 3

See Also

Reference

Control.MailboxProcessor<'Msg> Class (F#)

Microsoft.FSharp.Control Namespace (F#)

Change History

Date

History

Reason

January 2011

Added code example.

Information enhancement.