技术开发 频道

Remoting基本原理及其扩展机制(下)

IT168技术文档】

    让我们在开始本节内容之前先了解以下几个基本概念。 

    应用程序域

   应用程序域(通常简称为AppDomain)可以视为一种轻量级进程。一个Windows进程内可以包含多个AppDomain。AppDomain这个概念的提出是为了实现在一个物理服务器中承载多个应用程序,并且这些应用能够相互独立。ASP.NET中利用AppDomain在同一个进程内承载了多组Web应用程序就是一个例子。实际上微软曾进行过在单一进程内承载多达1000个简单Web应用程序的压力测试。

    使用AppDomain所获得的性能优势主要体现在两方面:

    1.创建AppDomain所需要的系统资源比创建一个Windows进程更少。
    2.同一个Windows进程内所承载的AppDomain之间可以互相共享资源,如CLR、基本.NET类型、地址空间以及线程。

    而各个AppDomain之间的独立性体现为以下这些特征:

    1.一个AppDomain可以独立于其他的AppDomain而被卸载。
    2.一个AppDomain无法访问其他AppDomain的程序集和对象。 
    3.若没有发生跨边界的异常抛出,一个AppDomain拥有自己独立的异常管理策略。这意味着一个AppDomain内出现问题不会影响到同一个进程内中的其他AppDomain。
    4.每个AppDomain可以分别定义独自的程序集代码访问安全策略。
    5.每个AppDomain可以分别定义独自的规则以便CLR在加载前定位程序集所在位置。

    可以看出应用程序域是进程中的一个子单元,不过在.NET中还存在一个比应用程序域还要细粒度的单元——.NET上下文(Context)。

    .NET Context

    一个.NET 应用程序域能够包含多个被称为.NET上下文的实体。所有.NET对象都存在于上下文中,每个应用程序域中至少存在一个上下文。这个上下文称为应用程序域的默认上下文,它在应用程序域创建的时候就创建了。下图总结了它们之间的关系:


    那么MessageSink与上下文有什么关系呢? 我们知道在通常情况下,如果访问同一个AppDomain中对象的方法时,会采用基于栈的方式(详见本系列上部)。在这种情况下,我们是无法拦截其中的消息的,因为此时根本不存在消息对象。只有当我们通过Transparent Proxy访问另一个对象的方法时,才会采用基于消息的方式。而现在我们只知道当一个对象调用处在另一个AppDomain中的远程对象(该对象为MarshalByRefObject子类)时,Remoting才会为调用方创建那个远程对象的Transparent Proxy。在了解了.NET上下文的概念后,你会发现,即使处在同一个AppDomain中的两个对象,如果它们所处的上下文不同,在访问对方的方法时,也会借由Transparent Proxy实现,即采用基于消息的方法调用方式。此时,我们就可以在上下文中插入MessageSink了。那么在上下文中是否存在类似IClientChannelSinkProvider的接口呢?很幸运,在经过一番探索后,我们发现确实存在类似的接口,而且还不止一个:IContributeEnvoySink、IContributeServerContextSink、IContributeObjectSink、IContributeClientContextSink这四个接口中各自包含了一个GetXXXSink的方法,它们都会返回一个实现了IMessageSink接口的对象。我们知道IClientChannelSinkProvider接口是配合配置文件最终实现向Pipeline中加入ChannelSink的,而以上这四个接口并没有配合配置文件使用,不过与IClientChannelSinkProvider的使用方式倒也有异曲同工之效。读者可以将下面这幅图与本系列上部中的图2比较一番。


    在上图中又出现了很多新的概念,下面将对它们一一做出解释:

0
相关文章