MailboxProcessor<'Msg> is an in-process agent: a single loop reads messages one at a time, so its private state needs no locks.
F# Expert · Lesson 1 · On the house
MailboxProcessor agents
Actor-style state with MailboxProcessor, Post, PostAndReply, and message DUs. Lesson 1 is free — on the house.
Lessons · F# Expert · Lesson 1 of 10 · On the house
MailboxProcessor agents
Actor-style state with MailboxProcessor, Post, PostAndReply, and message DUs.

Model messages as a DU. Requests that need an answer carry an AsyncReplyChannel<'T>.
agent.Post msg is fire-and-forget; agent.PostAndReply(fun ch -> Get ch) blocks for the reply (PostAndAsyncReply awaits).
The loop is a recursive async function: let rec loop state = async { let! msg = inbox.Receive() ... return! loop newState }.
Unhandled exceptions kill the agent silently unless you subscribe to agent.Error.
agent
type Msg =
| Add of int
| Get of AsyncReplyChannel<int>
let counter = MailboxProcessor.Start(fun inbox ->
let rec loop total = async {
let! msg = inbox.Receive()
match msg with
| Add n -> return! loop (total + n)
| Get ch ->
ch.Reply total
return! loop total
}
loop 0)
[1 .. 100] |> List.iter (fun n -> counter.Post (Add n))
printfn "%d" (counter.PostAndReply Get)
let posts = [ for _ in 1 .. 4 -> async { for _ in 1 .. 250 do counter.Post (Add 1) } ]
posts |> Async.Parallel |> Async.RunSynchronously |> ignore
printfn "%d" (counter.PostAndReply Get)
Quiz
Quiz
Quiz
Quiz
Check
Match the still for: MailboxProcessor agents.
Open-book: the answers are on this page. Pass every quiz and check (5) to mark the lesson done. This visit: 0/5.