深入了解.NET上下文
3.1 .NET上下文的概念
应用程序域是进程中承载程序集的逻辑分区,在应用程序域当中,存在更细粒度的用于承载.NET对象的实体,那就.NET上下文Context。
所有的.NET对象都存在于上下文当中,每个AppDomain当中至少在于一个默认上下文(context 0)。
一般不需要指定特定上下文的对象被称为上下文灵活对象(context-agile),建立此对象不需要特定的操作,只需要由CLR自行管理,一般这些对象都会被建立在默认上下文当中。
图3.0
3.2 透明代理
在上下文的接口当中存在着一个消息接收器负责检测拦截和处理信息,当对象是MarshalByRefObject的子类的时候,CLR将会建立透明代理,实现对象与消息之间的转换。
应用程序域是CLR中资源的边界,一般情况下,应用程序域中的对象不能被外界的对象所访问。而MarshalByRefObject 的功能就是允许在支持远程处理的应用程序中跨应用程序域边界访问对象,在使用.NET Remoting远程对象开发时经常使用到的一个父类。
但此文章针对的是进程与应用程序域的作用,关于.NET Remoting远程对象开发可参考:“回顾.NET Remoting分布式开发”
3.3 上下文绑定
当系统需要对象都使用消息接收器机制的时候,即可使用ContextBoundObject类。ContextBoundObject继承了MarshalByRefObject类,保证了它的子类都会通过透明代理被访问。
在第一节介绍过:一般类所建立的对象为上下文灵活对象(context-agile),它们都由CLR自动管理,可存在于任意的上下文当中。而 ContextBoundObject 的子类所建立的对象只能在建立它的对应上下文中正常运行,此状态被称为上下文绑定。其他对象想要访问ContextBoundObject 的子类对象时,都只能通过代透明理来操作。
下面的例子,是上下文绑定对象与上下文灵活对象的一个对比。Example 是一个普通类,它的对象会运行在默认上下文当中。而ContextBound类继承了ContextBoundObject,它的对象是一个上下文绑定对象。ContextBound还有一个Synchronization特性,此特性会保证ContextBound对象被加载到一个线程安全的上下文当中运行。另外,Context类存在ContextProperties属性,通过此属性可以获取该上下文的已有信息。
1 class Program
2 {
3 public class Example
4 {
5 public void Test()
6 {
7 ContextMessage("Example Test\n");
8 }
9 //访问上下文绑定对象测试
10 public void Sync(ContextBound contextBound)
11 {
12 contextBound.Test("Example call on contextBound\n");
13 }
14 }
15
16 [Synchronization]
17 public class ContextBound:ContextBoundObject
18 {
19 public void Test(string message)
20 {
21 ContextMessage(message);
22 }
23 }
24
25 static void Main(string[] args)
26 {
27 Example example = new Example();
28 example.Test();
29 ContextBound contextBound = new ContextBound();
30 contextBound.Test("ContentBound Test\n");
31 example.Sync(contextBound);
32 Console.ReadKey();
33 }
34
35 //显示上下文信息
36 public static void ContextMessage(string data)
37 {
38 Context context = Thread.CurrentContext;
39 Console.WriteLine(string.Format("{0}ContextId is {1}", data, context.ContextID));
40 foreach (var prop in context.ContextProperties)
41 Console.WriteLine(prop.Name);
42 Console.WriteLine();
43 }
44 }
运行结果
由运行结果可以发现,example对象一般只会工作于默认上下文context 0 当中,而contextBound则会工作于线程安全的上下文 context 1当中。当example需要调用contextBound对象时,就会通过透明代理把消息直接传递到context 1中。
============ 欢迎各位老板打赏~ ===========
与本文相关的文章
- · The instance of entity type ‘Customer’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked.
- · .NET8实时更新nginx ip地址归属地
- · 解决.NET Blazor子组件不刷新问题
- · .NET8如何在普通类库中引用 Microsoft.AspNetCore
- · .NET8 Mysql SSL error
- · ASP.NET Core MVC的Razor视图渲染中文乱码的问题
- · .NETCORE 依赖注入服务生命周期
- · asp.net zero改mysql
- · .NET5面试汇总
- · .Net连接Mysql数据库的Convert Zero Datetime日期问题
- · vue使用element-ui中的Message 、MessageBox 、Notification
- · Asp.Net Core Filter 深入浅出的那些事-AOP