【发布时间】:2011-08-12 05:24:39
【问题描述】:
在演员模型中,演员有某种消息循环,其中消息使用例如匹配。模式匹配(取决于c语言)
例如伪F#
let message_loop() =
let! message = receive_message() //sync receive message
match message with
| Foo(a,b) -> DoStuff(a,b)
| Bar(c) -> DoOtherStuff(c)
| _ -> error ("unknown message")
message_loop()
差不多,一个消息签名被匹配并与对消息内容执行的某些操作相关联。
this 和调用实际方法有什么概念上的区别吗? 例如如果我要在 C# 5 中执行以下操作:
class MyActor
{
//message signature Foo(a,b)
public void Foo(int a,string b)
{
Act( () => DoStuff(a,b) );
}
//message signature Bar(c)
public void Bar(int c)
{
Act( () => DoOtherStuff(c));
}
// the rest is infrasturcture code, can be refactored into an Actor Base class
//this emulates the sync behavior of the above actor
//each action is pushed onto a queue
//and then processed synchronously by the message handler
private void Act(Action action)
{
actions.Post(action);
}
private BufferBlock<Action> actions = new BufferBlock<Action>();
//this needs max degreee of parallellism = 1
private ActionBlock<Action> messageHandler = new ....
}
这样,在 MyActor 上调用方法将导致将异步消息发布到仅处理一种消息的消息队列中;一种行为。 但是,与消息关联的行为包含在消息本身中(从公共方法发布)
那么在 C# 5 / Async CTP 中,这是否被认为是一种干净的方式来处理演员?
好处是消息被简单地定义为普通消息,而不是像类一样创建笨拙的消息 DTO。
那么这是否足以让它发挥作用?
【问题讨论】:
-
这种风格的问题在 Code Review 中感觉更自在。这对我的口味来说有点开放。 codereview.stackexchange.com
-
如果使用 C#,我强烈建议学习 Rx。它非常强大、高效且富有表现力。你应该能够用 Rx 来模拟你的问题。我什至有时会推荐 Rx 用于 F#,而不是面向代理的方法。另外,Rx 团队已经涵盖了许多在 C# 中实现时可能出现错误的极端情况。
-
您提到的缓冲区块是 TPL 数据流的一部分,它本身就是一个参与者模型。您实际上可以使用此模型为 MailboxPProcessor 建模。我写了一系列帖子来演示这一点,您可能会觉得这很有用:moiraesoftware.com/blog/2012/01/22/FSharp-Dataflow-agents-I