mailbox 编程_MailboxProcessor从C#

虽然可以使用MailboxProcessor< T>直接从C#(使用C#异步扩展),如我的另一个答案中所指出的,这不是一件好事 – 我主要是为了好奇而写的.

邮箱处理器< T>类型被设计为从F#使用,所以它不适合C#编程模型.你可能可以为C#实现类似的API,但它不会那么好(当然不是C#4.0). TPL DataFlow library (CTP)为C#的未来版本提供了类似的设计.

目前,最好的做法是使用MailboxProcessor< T>实现代理.在F#中,通过使用Task对C#使用做出友好的评价.这样,您可以在F#(使用尾递归和异步工作流程)中实现代理的核心部分,然后组合&使用它们从C#.

我知道这可能不会直接回答你的问题,但我认为这是值得一个例子 – 因为这真的是将F#代理(MailboxProcessor)与C#相结合的唯一合理的方法.

我最近写了一个简单的“聊天室”演示,所以这里是一个例子:

type internal ChatMessage =

| GetContent of AsyncReplyChannel

| 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#将会更好.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值