c# 4.0 -<T> 来自 C# 的邮箱处理器



您是否尝试过使用c#中的T的MailboxProcessor ?你能张贴样例代码吗?

你如何开始一个新的,向它发布消息,你如何处理它们?

虽然您可以直接从c#中使用MailboxProcessor<T>(使用c# async扩展),正如我在另一个答案中指出的那样,这并不是一件好事-我写那篇文章主要是出于好奇。

MailboxProcessor<T>类型被设计为从f#中使用,因此它不太适合c#编程模型。您可能可以为c#实现类似的API,但它不会那么好(在c# 4.0中肯定不会)。TPL数据流库(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 )

这将在c# 4.0中相当可用(使用标准方法,如Task.WaitAll等),当您能够使用c# await关键字处理任务时,它将在c#的下一个版本中更好。

这个解决方案需要c#的"async CTP",但是看看c#中使用新的async/await的Agent/MailboxProcessor

相关内容

  • 没有找到相关文章

最新更新