Actor模型的本质已经被强调了无数遍:万物皆Actor。Actor之间只有发送消息这一种通信方式,例如,无论是管理员让工作者干活,还是工作者把成果交还给管理员,它们之间也要通过发送消息的方式来传递信息。这么做看似不如直接方法调用来的直接,但是由于大量的消息可以同时执行。同样,消息让Actor之间解耦,消息发出之后执行成功还是失败,需要耗费多少时间,只要没有消息传递回来,这一切都和发送方无关。Actor模型的消息传递形式简化了并行程序的开发,使开发人员无需在共享内存(确切地说,其实是共享“写”)环境中与“锁”、“互斥体”等常用基础元素打交道。不过,使用Actor模型编写应用程序,需要开发人员使用一种与以往不同的设计思路,这样的思路说难倒不难,说简单也不简单。等我们有了成熟、稳固的Actor模型之后(例如高效的调度,合适的容错机制,老赵正在为此努力),再回头来探究这种特殊的架构方式。
由于Actor执行的唯一“事件”便是接受到了一个消息,而一个Actor很可能会做多件事情,因此我们一定需要一种机制,可以把消息“分派”到不同的“逻辑段”中去,并为不同的逻辑指定各自所需要的参数。例如,Person是一个Actor类型,它有三种任务,不同的任务会带有不同参数:
◆聊天(Chat):指定另一个Person对象(聊天的另一方),以及一个Topic对象(聊天的话题)。
◆吃饭(Eat):指定一个Restaurant对象(餐馆)。
◆干活(Work):指定一个Person对象(工作完成后的汇报人),以及一个Job对象(任务)。
当Person对象获得一条消息时,它需要将其识别为聊天、吃饭或干活中的一种,再从中获取到这个行动所需要的数据。如果用一幅示意图来表示,它可能是这样的:
如何在C#中把一条消息转化为一段逻辑的执行,并且尽可能确保一些优势(如易于编写,静态检查,代码提示,重构,单元测试……),这便是这系列文章唯一的目的。正如文章的标题,我们关注的是“消息执行方式”,而不是:
◆“消息传递”与“共享内存”两种并行方式的比较
◆讲述Actor模型的应用程序设计方式。
◆提出消息传递时的解耦方式。
……
文章使用Actor模型作为示例,是因为我编写的ActorLite组件易于说明问题,并且是典型的“消息传递”场景。事实上,文章所表达的内容,适合任何基于消息传递的C#场景,例如内存中的消息队列、生产者/消费者模式、消息总线……它并没有限制Actor模型这一种架构方式。
【编辑推荐】