Have you tried to use a MailboxProcessor of T from C#? Could you post sample code?
How do you start a new one, post messages to it, and how do you process them?
Have you tried to use a MailboxProcessor of T from C#? Could you post sample code?
How do you start a new one, post messages to it, and how do you process them?
While you can use MailboxProcessor<T>
directly from C# (using the C# async
extension) as pointed out in my other answer, this isn't really a good thing to do - I wrote that mainly for curiosity.
The MailboxProcessor<T>
type was designed to be used from F#, so it doesn't fit well with the C# programming model. You could probably implement similar API for C#, but it wouldn't be that nice (certainly not in C# 4.0). The TPL DataFlow library (CTP) provides similar design for the futrue version of C#.
Currently, the best thing to do is to implement the agent using MailboxProcessor<T>
in F# and make it friendly to C# usage by using Task
. This way, you can implement the core parts of agents in F# (using tail-recursion and async workflows) and then compose & use them from C#.
I know this may not directly answer your question, but I think it's worth giving an example - because this is really the only reasonable way to combine F# agents (MailboxProcessor
) with C#.
I wrote a simple "chat room" demo recently, so here is an example:
type internal ChatMessage =
| GetContent of AsyncReplyChannel<string>
| SendMessage of string
type ChatRoom() =
let agent = Agent.Start(fun agent ->
let rec loop messages = async {
// Pick next message from the mailbox
let! msg = agent.Receive()
match msg with
| SendMessage msg ->
// Add message to the list & continue
let msg = XElement(XName.Get("li"), msg)
return! loop (msg :: messages)
| GetContent reply ->
// Generate HTML with messages
let html = XElement(XName.Get("ul"), messages)
// Send it back as the reply
reply.Reply(html.ToString())
return! loop messages }
loop [] )
member x.SendMessage(msg) = agent.Post(SendMessage msg)
member x.AsyncGetContent() = agent.PostAndAsyncReply(GetContent)
member x.GetContent() = agent.PostAndReply(GetContent)
So far, this is just a standard F# agent. Now, the interesting bits are the following two methods that expose GetContent
as an asynchronous method usable from C#. The method returns Task
object, which can be used in the usual way from C#:
member x.GetContentAsync() =
Async.StartAsTask(agent.PostAndAsyncReply(GetContent))
member x.GetContentAsync(cancellationToken) =
Async.StartAsTask
( agent.PostAndAsyncReply(GetContent),
cancellationToken = cancellationToken )
This will be reasonably usable from C# 4.0 (using the standard methods such as Task.WaitAll
etc.) and it will be even nicer in the next version of C# when you'll be able to use the C# await
keyword to work with tasks.
This solution requires the C# "async CTP" but take a look at Agent/MailboxProcessor in C# using new async/await
© 2022 - 2024 — McMap. All rights reserved.