zoukankan      html  css  js  c++  java
  • 代理

    首先来了解下应用程序与的概念。

          应用程序域:windows操作系统运行的基本单位是进程,而进程是直接运行于非托管的环境下的,我们的.NET应用程序最终也是需要运行在进程之上。可是我们得知.NET应用程序是要运行在托管环境下的,进程的运行环境是非托管的。这时就需要一个中介者,运行于非托管的进程之上,并向我们的.NET应用程序提供托管环境,这就是AppDomain应用程序域。而且一个进程可以有若干个应用程序域。这样可以减少进程频繁切换带来的性能开销。在以前的windows程序下我们不能直接跨越进程来访问另外一个进程的对象,这属于进程的隔离级别,在.NET应用程序下,我们不能直接跨越应用程序来访问另外一个应用程序域的对象。如下代码:

    // 在新AppDomain中创建一个对象
    static void Test2() {
    AppDomain currentDomain
    = AppDomain.CurrentDomain;
    Console.WriteLine(currentDomain.FriendlyName);

    // 创建一个新的应用程序域 - NewDomain
    AppDomain newDomain = AppDomain.CreateDomain("NewDomain");

    DemoClass obj;
    // 在新的应用程序域中创建对象
    obj = (DemoClass)newDomain.CreateInstanceAndUnwrap("ClassLib", "ClassLib.DemoClass");
    obj.ShowAppDomain();
    obj.ShowCount(
    "Jimmy");
    obj.ShowCount(
    "Jimmy");
    }

           从上面的代码可以看出,DemoClass的obj对象是在当前应用程序域声明的,其引用是在当前应用程序域的。而这句代码:obj = (DemoClass)newDomain.CreateInstanceAndUnwrap("ClassLib", "ClassLib.DemoClass");是将其引用指向另外一个引用程序域的实列。运行上面的程序会出错。会出现一个异常:类型“ClassLib.DemoClass”未标记为可序列化。当把DemoClass标记为可序列化之后,上面的代码就不会出现异常。上面这些事参照张子阳老兄博客的。他的解释是这样的:标记为可序列化之后,源应用程序域会将该类的对象序列化,然后传递到目标域,将其进行反序列化,还原对象。赋值给引用。

           按照他的解释,将传递过来的对象反序列化之后,会在托管堆上给传递过来的实列分配一个地址。然后赋值给引用。但是这个对象只是一个代理而已。
           代理(Proxy): 提供了和远程对象(本例中是在NewDomain中创建的DemoClass对象)完全相同的接口(属性和方法)。.Net需要在客户端(本例中是ConsoleApp.exe)基于远程对象的元信息(metadata)创建代理。因此客户端必须包含远程对象的元信息(简单来说就是只包含名称及接口定义,但可以不包含实际的代码实现)。因为代理有着和远程对象完全一样的接口和名称,所以对于客户程序来说,代理就好像是远程对象一样;而代理实际上又并不包含向客户程序提供服务的实际代码(比如说方法体),所以代理仅仅是将自己与某一对象相绑定,然后把客户程序对自己的服务请求发送给对象。对于客户程序来说,远程对象(服务端对象)就好像是在本地;而对远程对象来说,也好像是为其本地程序提供服务。

           传值封送:上面这种通过调用CreateInstanceAndUnWrap()方法这种方式进行传值封送是一种特例。就是将整个对象传递给客户端。

           引用封送:让对象依然保留在远程(本例为NewDomain中),而在客户端仅创建代理,上面已经说了代理的接口和远程对象完全相同,所以客户端以为仍然访问的是远程对象,当客户端调用代理上的方法时,由代理将对方法的请求发送给远程对象,远程对象执行方法请求,最后再将结果传回。但是和传值封送的区别还不是很明显。难道是传值封送将方法的实现也传递过来,而引用封送传递的是方法名称和接口定义?

  • 相关阅读:
    51NOD 1069 Nim游戏
    51NOD 1066 Bash游戏
    51NOD 1058 N的阶乘的长度
    51NOD 1057 N的阶乘
    51NOD 1027 大数乘法
    RMQ 区间最大值 最小值查询
    Codeforces Round #426 (Div. 2) C. The Meaningless Game
    51NOD 1046 A^B Mod C
    OJ上 编译器 G++和C++的区别
    二分暑假专题 训练记录 2017-7-29
  • 原文地址:https://www.cnblogs.com/cpetcoandy/p/2193975.html
Copyright © 2011-2022 走看看