读书笔记(二)对象激活和上下文

简介: 任何程序都需要在某个平台提供的环境中执行.对于传统的炒作系统而言,这种运行时环境的主要形式就是一个进程.一个进程不仅为你的代码提供了象虚拟内存,线程和内核对象这样的资源,还为你和别人的代码间提供了一个隔离边界.

任何程序都需要在某个平台提供的环境中执行.对于传统的炒作系统而言,这种运行时环境的主要形式就是一个进程.一个进程不仅为你的代码提供了象虚拟内存,线程和内核对象这样的资源,还为你和别人的代码间提供了一个隔离边界.这种隔离不仅带来了某种程度上的保护,这样你的代码不会受到别人错误代码的影响还给你的程序提供一种独有的特性,比如可以单独的做安全配置,或者当前目录路径.

代码隔离在进程之间和进程内部都是游泳的.COM,COM+和公用语言运行时CLR都已经建立了这种模型以在进程内部内部提供细颗粒的代码隔离.COM+CLR,这种细颗粒的隔离单元被称为上下文(context).

COM+上下文是COM单元的一部分,COM单元本身是用于对线程对象分组的进程的一部分.CLR上下文是CLR应用程序的一部分,CLR应用程序域本身是用于对共享相同安全和版本策略的对象分组的进程的一部分.上下文是COM+.NET企业服务的编程模型的核心.每个被配置在COM+目录中的组件都会被自动的关联一个上下文.这种上下文使得系统拦截成为可能.

COM+里配置的那些对象总是在一个上下文内运行.对象所需要的上下文由服务组件类上设定的上下文特性所定义.这些上下文特性定义了一个组件对于运行环境的需求.如果这里对象的调用这已经运行于一个上下文中.(因为它也是一个已配置的组件),则会检查这个上下文时候和这里对象所需要的相兼容.如果是,则这个对象将在调用者所在的上下文中运行.

如果这个上下文和这个对象所定西的不兼容,则将建立一个新的上下文.CLRCOM+都依赖于代理以保证对象间的上下文边界.代理(proxy)是处于不同的上下文中的真实对象的一个替身对象,代理负责在一二方法调用转换上下文.

既然上下文是根据一组用于声明对象所需要运行环境的属性来规定的,为一个对象定义一个上下文意味着这个对象支农从这个上下文内部直接访问.如果访问该对象的调用者所在上下文有所不同的化,则它不能直接调用该对象上的方法.而要通过一个代理.

(简单对象和上下文无关.普通的.NET对象都是简单对象,COM 对象总是绑定到一个上下文)

简单对象(Agile Object)

绑定了上下文的对象(Context Bound Object/CBO)

.NET用于实现夸上下文通信的技术是.NET Remoting.所以CBO类和SynchroizationAttribute(继承自ContextAttribute)被放在System.Runtime.Remoting.Context命名空间下.

.NET的安全边界:应用户程序域,一个进程可以包含多个应用程序域,来自一个域的对象不能和其他域的对象直接互相操作,互相操作用的是应用程序域信道.

 1 img_a6339ee3e57d1d52bc7d02b338e15a60.gif using  System;
 2 img_a6339ee3e57d1d52bc7d02b338e15a60.gif using  System.Threading;
 3 img_a6339ee3e57d1d52bc7d02b338e15a60.gif using  System.Runtime.Remoting.Contexts;
 4 img_a6339ee3e57d1d52bc7d02b338e15a60.gif
 5 img_a6339ee3e57d1d52bc7d02b338e15a60.gif[Synchronization]
 6 img_a6339ee3e57d1d52bc7d02b338e15a60.gif class  A:ContextBoundObject
 7 img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif {
 8img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    public void Method1() img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
 9img_33d02437d135341f0800e3d415312ae8.gif        string threadName = Thread.CurrentThread.Name;
10img_33d02437d135341f0800e3d415312ae8.gif        Console.WriteLine(threadName + ": Method1 started");
11img_33d02437d135341f0800e3d415312ae8.gif        Thread.Sleep(3000);
12img_33d02437d135341f0800e3d415312ae8.gif        Console.WriteLine(threadName + ": Method1 finished");
13img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

14img_05dd8d549cff04457a6366b0a7c9352a.gif}

15 img_a6339ee3e57d1d52bc7d02b338e15a60.gif
16 img_a6339ee3e57d1d52bc7d02b338e15a60.gif class  Test
17 img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif {
18img_33d02437d135341f0800e3d415312ae8.gif    A obj = new A();
19img_33d02437d135341f0800e3d415312ae8.gif
20img_33d02437d135341f0800e3d415312ae8.gif    public void ThreadMethod()
21img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
22img_33d02437d135341f0800e3d415312ae8.gif        obj.Method1();
23img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

24img_33d02437d135341f0800e3d415312ae8.gif
25img_33d02437d135341f0800e3d415312ae8.gif    static void Main(string[] args)
26img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
27img_33d02437d135341f0800e3d415312ae8.gif        Test test = new Test();
28img_33d02437d135341f0800e3d415312ae8.gif
29img_33d02437d135341f0800e3d415312ae8.gif        //create and start a thread
30img_33d02437d135341f0800e3d415312ae8.gif        Thread t1 = new Thread(new ThreadStart(test.ThreadMethod));
31img_33d02437d135341f0800e3d415312ae8.gif        t1.Name = "Thread 2";
32img_33d02437d135341f0800e3d415312ae8.gif        t1.Start();
33img_33d02437d135341f0800e3d415312ae8.gif
34img_33d02437d135341f0800e3d415312ae8.gif        //invoke Method1 with the main thread
35img_33d02437d135341f0800e3d415312ae8.gif        Thread.CurrentThread.Name = "Thread 1";
36img_33d02437d135341f0800e3d415312ae8.gif        test.obj.Method1();
37img_33d02437d135341f0800e3d415312ae8.gif        t1.Join();
38img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

39img_05dd8d549cff04457a6366b0a7c9352a.gif}

 

      所有服务组件的基类都是在System.EnterpriseService命名空间下的ServicedComponent.这个类继承于System.ContextBoundObject,所有服务组件都有一个.NET Remoting上下文.

      当一个.NET服务组件被创建时,此时不仅建立了.NET上下文,还建立了一个连接到.NET上下文的COM+上下文.

相关文章
|
10月前
|
缓存 算法 Java
《深入理解Java虚拟机》读书笔记(四)--GC的回收条件及Java对象的引用
《深入理解Java虚拟机》读书笔记(四)--GC的回收条件及Java对象的引用
204 0
|
10月前
|
存储 缓存 算法
《深入理解Java虚拟机》读书笔记(二)--对象的创建与空间分配及定位
《深入理解Java虚拟机》读书笔记(二)--对象的创建与空间分配及定位
89 0
|
存储 缓存 算法
深入理解JVM虚拟机读书笔记——对象的创建与内存布局
注:本文参考自周志明老师的著作《深入理解Java虚拟机(第3版)》,相关电子书可以关注WX公众号,回复 001 获取。
深入理解JVM虚拟机读书笔记——对象的创建与内存布局
|
存储 网络协议 安全
读书笔记 之《Thinking in Java》(对象、集合、异常)
一、前言     本来想看完书再整理下自己的笔记的,可是书才看了一半发现笔记有点多,有点乱,就先整理一份吧,顺便复习下前面的知识,之后的再补上。     真的感觉,看书是个好习惯啊,难怪人家说“书籍是人类进步的阶梯”。
1116 0
|
C++ 容器 存储
读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)
假设你正在操作一个Rectangle类。每个矩形可以通过左上角的点和右下角的点来表示。为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放入一个辅助结构体中,Rectangle中声明一个指向它的指针就可以了: 1 class...
928 0
|
C++
读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
1. 问题的提出:要求函数返回对象时,可以返回引用么? 一旦程序员理解了按值传递有可能存在效率问题之后(Item 20),许多人都成了十字军战士,决心清除所有隐藏的按值传递所引起的开销。对纯净的按引用传递(不需要额外的构造或者析构)的追求丝毫没有懈怠,但他们的始终如一会产生致命的错误:它们开始传递指向并不存在的对象的引用。
914 0
|
C# C++ 编译器
读书笔记 effective c++ Item 17 使用单独语句将new出来的对象放入智能指针
1. 可能会出现资源泄漏的一种用法 假设我们有一个获取进程优先权的函数,还有一个在动态分配的Widget对象上根据进程优先权进行一些操作的函数: 1 int priority(); 2 3 void processWidget(std::tr1::shared_ptr pw, int priority); 注意这里使用了对象管理资源的用法(Item 13),processWidget为它需要处理的动态分配对象Widget使用了智能指针(tr1::shared_ptr)。
840 0
|
C++ 容器
读书笔记 effective c++ Item 13 用对象来管理资源
1.不要手动释放从函数返回的堆资源 假设你正在处理一个模拟Investment的程序库,不同的Investmetn类型从Investment基类继承而来, 1 class Investment { .
997 0
|
C++ 编译器 安全
读书笔记 effective c++ Item 12 拷贝对象的所有部分
1.默认构造函数介绍 在设计良好的面向对象系统中,会将对象的内部进行封装,只有两个函数可以拷贝对象:拷贝构造函数和拷贝赋值运算符。我们把这两个函数统一叫做拷贝函数。从Item5中,我们得知,如果需要的话编译器会为你生成这两个拷贝函数,并且编译器生成的版本能够精确的做到你想做的:它们拷贝了对象的所有数据。
822 0