您是否尝试过在C#中使用MailboxProcessor of T?您能否提供示例代码?
如何启动一个新的进程,向其发布消息,并如何处理它们?
您是否尝试过在C#中使用MailboxProcessor of T?您能否提供示例代码?
如何启动一个新的进程,向其发布消息,并如何处理它们?
虽然你可以使用C#的async
扩展直接使用MailboxProcessor<T>
(如我在其他答案中所指出的),但这并不是一个好习惯——我主要是出于好奇心写的。
MailboxProcessor<T>
类型是为F#设计的,因此它与C#编程模型不太匹配。你可能可以为C#实现类似的API,但那不会很好(尤其是在C# 4.0中)。TPL DataFlow库(CTP)提供了类似的设计,适用于未来版本的C#。
目前最好的做法是,在F#中使用MailboxProcessor<T>
实现代理,并通过使用Task
使其对C#友好。这样,你可以使用F#(使用尾递归和异步工作流程)实现代理的核心部分,然后从C#中组合和使用它们。
我知道这可能不能直接回答你的问题,但我认为值得举个例子——因为这真的是将F#代理(MailboxProcessor
)与C#结合的唯一合理方式。
我最近写了一个简单的“聊天室”演示,所以这里是一个例子:
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)
到目前为止,这只是一个标准的F#代理。现在,有趣的部分是以下两个方法,它们将GetContent
公开为可从C#中使用的异步方法。该方法返回Task
对象,可以像通常在C#中使用一样:
member x.GetContentAsync() =
Async.StartAsTask(agent.PostAndAsyncReply(GetContent))
member x.GetContentAsync(cancellationToken) =
Async.StartAsTask
( agent.PostAndAsyncReply(GetContent),
cancellationToken = cancellationToken )
使用标准方法(如Task.WaitAll
等)从C# 4.0开始,这将是相当可用的,在C#的下一个版本中,您甚至可以使用C# await
关键字来处理任务,那时它会更加方便。
这个解决方案需要使用 C# 的 "async CTP",但是可以看一下 Agent/MailboxProcessor in C# using new async/await。