您是否尝试过使用C#的T的MailboxProcessor?你能发贴示例代码吗?
你如何开始一个新的,发布消息,以及如何处理它们?
您是否尝试过使用C#的T的MailboxProcessor?你能发贴示例代码吗?
你如何开始一个新的,发布消息,以及如何处理它们?
虽然你可以使用 MailboxProcessor<T>
直接来自C#(使用C# async
在我的另一个答案中指出,这不是一件好事 - 我写的主要是为了好奇。
该 MailboxProcessor<T>
type被设计为从F#中使用,因此它不适合C#编程模型。您可能可以为C#实现类似的API,但它不会那么好(当然不是在C#4.0中)。该 TPL DataFlow库(CTP) 为C#的futrue版本提供了类似的设计。
目前,最好的办法是使用代理实现代理 MailboxProcessor<T>
在F#中,通过使用它使C#使用友好 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
用于处理任务的关键字。
虽然你可以使用 MailboxProcessor<T>
直接来自C#(使用C# async
在我的另一个答案中指出,这不是一件好事 - 我写的主要是为了好奇。
该 MailboxProcessor<T>
type被设计为从F#中使用,因此它不适合C#编程模型。您可能可以为C#实现类似的API,但它不会那么好(当然不是在C#4.0中)。该 TPL DataFlow库(CTP) 为C#的futrue版本提供了类似的设计。
目前,最好的办法是使用代理实现代理 MailboxProcessor<T>
在F#中,通过使用它使C#使用友好 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”,但请查看 C#中的Agent / MailboxProcessor使用新的async / await