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

Like MailboxProcessor.PostAndReply, but returns None if there is no reply within the timeout period.

Namespace/Module Path: Microsoft.FSharp.Control

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

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

// Usage:
mailboxProcessor.TryPostAndReply (buildMessage)
mailboxProcessor.TryPostAndReply (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. Defaults to -1 which corresponds to Infinite().

Return Value

The reply from the agent or None if the timeout expires.

Example

The following example shows how to use TryPostAndReply. In this example, the agent has a delay that eventually results in a timeout.

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();
                // The delay gets longer with each message, and eventually will trigger a timeout.
                do! Async.Sleep(200 * n );
                if (message = "Stop") then
                    replyChannel.Reply("Stop")
                else
                    replyChannel.Reply(String.Format(formatString, n, message))
                do! loop (n + 1)
        }
    loop 0)

let asyncReadInput =
   async {
       printf "> "
       let input = Console.ReadLine();
       return input
   }

printfn "Mailbox Processor Test"
printfn "Type some text and press Enter to submit a message."
printfn "Type 'Stop' to close the program."

let rec loop() =
    Async.StartWithContinuations(asyncReadInput, (fun input ->
        let reply = agent.TryPostAndReply((fun replyChannel -> input, replyChannel), 1000)
        match reply with
        | None -> printfn "Timeout exceeded."
        | Some(reply) ->
            if (reply <> "Stop") then
                printfn "Reply: %s" reply
                loop()
            else
                ()),
        (fun exn -> ()),
        (fun _ -> ()))
loop()

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

A sample session follows.

Mailbox Processor Test
Type some text and press Enter to submit a message.
Type 'Stop' to close the program.
> test1
Reply: Message number 0 was received. Message contents: test1
> test2
Reply: Message number 1 was received. Message contents: test2
> test3
Reply: Message number 2 was received. Message contents: test3
> test4
Reply: Message number 3 was received. Message contents: test4
> test5
Reply: Message number 4 was received. Message contents: test5
> test6
Timeout exceeded.
Press Enter to continue.

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.