在C#5 /异步CTP中实现Actor模型

|| 在参与者模型中,参与者具有某种消息循环,其中消息使用例如模式匹配(取决于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()
差不多,消息签名被匹配并与对消息内容执行的某些操作相关联。 这和调用实际方法之间在概念上有什么区别吗? 例如如果我要在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上调用方法将导致异步消息被发布到仅处理一种消息的消息队列中。一种行为。 但是,与消息关联的行为包含在消息本身中(从public方法发布) 那么,这是否被认为是在C#5 /异步CTP中执行角色的一种干净方法? 好处是,将消息简单地定义为普通消息,而不是创建类似类的尴尬消息DTO。 那么这足以使它工作吗?     
已邀请:
基于任务的异步与MailboxProcessor之间存在细微的差异。邮箱处理器将始终以相同的线程结尾,类似于Winforms消息循环。任务保留一个SynchronizationContext。对于Winforms和WPF,这意味着相同的行为,但是在使用线程池时,您可能最终在不同的线程上。 否则,从概念上讲,对我来说似乎正确。     
我会说你的方法是合理的。 实际上,将F#代理封装在接口后面,本身将消息分发给该代理是一种好习惯:
type IPrintText =
    abstract Stop : unit -> unit
    abstract Print : string -> unit

module Printer =
    type private Message =
        | PrintText of string
        | Stop

    let Start () =
        let agent =
            MailboxProcessor.Start (fun inbox ->
                    let rec loop () = async {
                            let! msg = inbox.Receive()

                            return!
                                match msg with
                                | PrintText text ->
                                    printfn \"%s\" text
                                    loop ()
                                | Stop -> async.Zero()
                        }
                    loop ())

        { new IPrintText with
            member x.Stop () = agent.Post Stop
            member x.Print text = agent.Post <| PrintText text }

let agent = Printer.Start ()

agent.Print \"Test\"
agent.Stop ()
    

要回复问题请先登录注册