JointCode.Shuttle,一个简单高效的跨 AppDomain 通信的服务框架

JointCode.Shuttle 是一个用于进程内 AppDomain 间通信的服务架构(不支持跨进程),它旨在取代运行时库提供的 MarshalByrefObject 的功能。

 

1. 使用场景

在 .net / mono 开发中,一般不太需要创建新的 AppDomain,但在一些 特定情况 下,也许我们需要使用一个新的 AppDomain,并在其中执行一些操作。

当代码跨越 AppDomain 边界访问另一个 AppDomain 时,便产生了跨 AppDomain 通信。这时候,您可以考虑使用 JointCode.Shuttle。

 

2. 传统跨 AppDomain 通信方式的问题

一般来说,在进行跨 AppDomain 调用时,大部分人使用运行时库默认提供的、基于 MarshalByrefObject 类继承的通信机制。这种方式最简单,只要让需要跨 AppDomain 操作的类继承 MarshalByrefObject 即可,实现起来很方便。例如:

 1 namespace JoitCode.Shuttle.SimpleSample
 2 {
 3     public class MyService : MarshalByRefObject
 4     {
 5         public void Do() { }
 6     }
 7 
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             // 在默认 AppDomain 中创建一个子 AppDomain
13             var serviceDomain = AppDomain.CreateDomain("ServiceDomain", null, null);
14             
15             var myService = (MyService)serviceDomain.CreateInstanceAndUnwrap
16                 (typeof(MyService).Assembly.FullName, 
17                  "JoitCode.Shuttle.SimpleSample.MyService");
18 
19             myService.Do();
20 
21             Console.Read();
22         }
23     }
24 }
View Code

简单是简单,但这种方式也有一些局限性。有什么局限性呢?

  • AppDomain 的访问是单点的,即它只能由创建它的宿主(或称父 AppDomain)访问,而不能由其他 AppDomain 访问,即使是由相同宿主创建的其他 AppDomain,甚至其宿主的父宿主也不行。
  • 缺少灵活性,由于要求服务类必须继承 MarshalByrefObject 类,这限制了灵活性。
  • 性能问题,测试结果表明使用这种方式的跨 AppDomain 通信要比普通对象访问慢几百到一千倍(示例
  • 双向通信,使用这种方式无法实现双向通信。

除了 MarshalByrefObject 之外,可能还有 remoting、wcf 甚至于消息队列等等跨进程的方式也可以实现跨 AppDomain 通信(作者自己没尝试过)。这些方式或多或少消除了上述那些限制,然而我们也能想象得到,本来是进程内通信的事情,现在弄成进程间通信,凭空增加许多开销,那么它们的性能一定比 MarshalByrefObject 更低,而且学习成本也会更高,实现起来也更复杂。

 

3. JointCode.Shuttle 的特点

与 MarshalByrefObject 相比,JointCode.Shuttle 除了具备相同的跨 AppDomain 通信的功能之外,还有自己的一些特点:

  1. 面向接口/服务
  2. 可以从一个 AppDomain 中访问任何 AppDomain 的服务(采用 MarshalByrefObject 方式,只能从父 AppDomain 访问子 AppDomain)
  3. 更好的性能:速度比 MarshalByrefObject 方式快 60~70 倍
  4. 服务可管理:可动态注册/注销服务组
  5. 使用 Attribute 方式来标注服务 / 定义服务元数据,对代码无侵入
  6. 强类型,使用方便(MarshalByrefObject 方式依赖 magic string 来查找服务类)
  7. 内置 IoC 功能,自动管理服务的依赖项
  8. 支持延迟加载类型 / 程序集
  9. 简单,快速上手
  10. 可通过租约方式管理远程服务生命期,也可自行管理(MarshalByrefObject 方式不提供远程服务生命期管理功能)
  11. 支持 .net 2.0


4. 未来计划

JointCode.Shuttle 是一个非常新颖的框架,功能还不是很完备。尽管作者将会在未来继续完善现有功能,并推出更多新的功能,但目前还是存在一些不足,主要包括:

  1. 仅支持 32 位应用程序(x86 目标平台)
  2. 仅支持 Windows(目前仅支持 .net framework,不支持 mono)
  3. 暂不支持跨 AppDomain 事件
  4. 测试得不够

 

5. 如何使用 JointCode.Shuttle

如果您对 JointCode.Shuttle 有兴趣,请移步前往 这里,我们提供了一个简单的示例来说明如何使用这个框架。

 

posted @ 2017-07-17 16:32  Johnny.Liu  阅读(690)  评论(1编辑  收藏  举报