技术开发 频道

C# Actor消息执行:阶段性总结

    风云兄提出,既然问题的关键在于强耦合,为什么不使用消息总线来解耦呢?其实这问题很容易回答。

    首先,“强耦合”并不是我们想要解决的问题。我们想要解决的是“消息执行”(见文章标题)而不是“消息传递”,“强耦合”只是我们得到满意的解决方案之前所遇到的困难而已。“消息总线”是消息传递时,系统(大粒度)组件之间的解耦方式。而现在我们要解开的,是Actor这种小粒度对象之间消息传递造成的耦合。在.NET消息传递过程中,消息是一个对象,一般在框架中使用TMessage表示。例如风云兄给出的代码,TMessage即为字符串。我们的目标是如何从一个TMessage类型的对象(如字符串)分配至不同的逻辑片断——还要携带参数过去。风云兄的例子回避了这一点。

    事实上,正如文章一开始所说的那样,我们文章得出的解决方案并不仅限于Actor模型,它适合各种消息传递场景——这些场景里自然包括“消息总线”的使用。关于文章的目的,“亚历山大同志”同学称之为“要在C#里面实现优雅的模式匹配的问题”。从一定角度上来说,老赵认为这个描述非常妥当,因为Erlang中模式匹配的目的便是消息执行。

    其实这可能也是基于Actor模型的程序架构方式还不为人熟悉的缘故。其实“消息总线”和“Actor模型”间的关系……不大,其相似性大概也只有“消息传递”这个特性而已。但是,在Actor模型中,消息是Actor对象间通信的唯一方式。Actor模型在使用时,内存中可能产生成千上万个Actor对象,它们互相发送消息产生交互。同时,Actor可以随时被创建出来,用完后又可以随时丢弃,因此Actor之间的通信无法“预先指定”。而“消息总线”需要在运行之前进行“注册”,然后它可以控制一条消息的Subject(即目标)。如果使用消息总线来实现Actor模型的话,则必须在Actor对象创建出来以后“注册”到消息总线,然后在Actor销毁之后“解开”。这又要求消息总线拥有高效的“注册”和“解开”操作,还必须完全是线程安全的。

    正是这个原因,Actor模型在使用时一般都是得到对方的引用并“直接”发送。而且,会把自己作为消息的一部分传递过去,这是为了让对方可以“直接”回复,这带来了程序设计过程中相当的灵活性。当然,这条消息可能会暂时放在Actor的队列中,等Actor空闲时再执行。这又是Actor模型的又一个特性:对于单个Actor来说,消息的执行完全是线程安全的。这大大简化了并行程序设计的难度,也是它与“共享内存”这种并行程序设计方式的区别。如果使用消息总线来实现Actor模型,它可以保证向一个Subject快速发送两条消息后,它们被依次执行吗?

    因此,如乒乓测试这种简单的消息传递示例,可以使用消息总线来实现,而复杂的场景就不合适了。在下一篇文章中,老赵会使用Actor模型来实现一个相对复杂的示例:网页小爬虫。在添加功能的过程中,您一定可以更好的了解Actor模型的使用方式,以及它在并行程序设计时的优势。

原文地址:http://www.cnblogs.com/jeffreyzhao/archive/2009/07/20/message-execution-model-for-c-sharp-actor-4-mid-stage-conclusion.html

0
相关文章