您是否尝试过在 C# 中使用 T 的 MailboxProcessor?你能发布示例代码吗?
你如何开始一个新的,向它发布消息,以及你如何处理它们?
您是否尝试过在 C# 中使用 T 的 MailboxProcessor?你能发布示例代码吗?
你如何开始一个新的,向它发布消息,以及你如何处理它们?
虽然您可以MailboxProcessor<T>
直接从 C# 中使用(使用 C#async
扩展名),正如我在其他答案中所指出的那样,但这并不是一件好事 - 我主要是出于好奇而写的。
该MailboxProcessor<T>
类型被设计为从 F# 中使用,因此它不适合 C# 编程模型。您可能可以为 C# 实现类似的 API,但它不会那么好(当然不是在 C# 4.0 中)。TPL DataFlow 库 (CTP)为 C#的未来版本提供了类似的设计。
目前,最好的办法是MailboxProcessor<T>
在 F# 中实现代理使用,并通过使用Task
. 这样,您可以在 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 )
这将在 C# 4.0 中合理使用(使用标准方法Task.WaitAll
等),并且在 C# 的下一个版本中,当您能够使用 C#await
关键字处理任务时,它会更好。
此解决方案需要 C#“异步 CTP”,但请使用新的 async/await 查看 C# 中的 Agent/MailboxProcessor