[英]MailboxProcessor<T> from C#
您是否嘗試過使用C#的T的MailboxProcessor? 你能發貼示例代碼嗎?
你如何開始一個新的,發布消息,以及如何處理它們?
雖然您可以直接使用來自C#的MailboxProcessor<T>
(使用C# async
擴展),如我在其他答案中所指出的那樣,這不是一件好事 - 我寫這篇文章主要是為了好奇。
MailboxProcessor<T>
類型設計用於F#,因此它不適合C#編程模型。 您可能可以為C#實現類似的API,但它不會那么好(當然不是在C#4.0中)。 TPL DataFlow庫(CTP)為C#的futrue版本提供了類似的設計。
目前,最好的辦法是使用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 )
這可以從C#4.0(使用諸如Task.WaitAll
等標准方法)合理地使用,並且當您能夠使用C# await
關鍵字來處理任務時,它將在下一版本的C#中更好。
此解決方案需要C#“async CTP”,但使用新的async / await查看C#中的Agent / MailboxProcessor
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.