NET上下文的概念

应用程序域是进程中承载程序集的逻辑分区,在应用程序域当中,存在更细粒度的用于承载.NET对象的实体,上下文是用来确定对象的逻辑归属,那就.NET上下文Context。
所有的.NET对象都存在于上下文当中,每个AppDomain当中至少存在一个默认上下文(context 0)。

即使处在同一个AppDomain中的两个对象,如果它们所处的上下文不同,在访问对方的方法时,也会借由Transparent Proxy实现,即采用基于消息的方法调用方式。
一般不需要指定特定上下文的对象被称为上下文灵活对象(context-agile),建立此对象不需要特定的操作,只需要由CLR自行管理,一般这些对象都会被建立在默认上下文当中。

透明代理

在上下文的接口当中存在着一个消息接收器负责检测拦截和处理信息,当对象是MarshalByRefObject的子类的时候,CLR将会建立透明代理,实现对象与消息之间的转换。

用程序域是CLR中资源的边界,一般情况下,应用程序域中的对象不能被外界的对象所访问。而MarshalByRefObject
的功能就是允许在支持远程处理的应用程序中跨应用程序域边界访问对象,在使用.NET Remoting远程对象开发时经常使用到的一个父类。
此文章针对的是进程与应用程序域的作用,关于MarshalByRefObject的使用已经超越了本文的范围,关于.NET Remoting 远程对象开发可参考:“回顾.NET Remoting分布式开发”

上下文绑定

当系统需要对象使用消息接收器机制的时候,即可使用ContextBoundObject类。ContextBoundObject继承了MarshalByRefObject类,保证了它的子类都会通过透明代理被访问。

第一节介绍过:一般类所建立的对象为上下文灵活对象(context-agile),它们都由CLR自动管理,可存在于任意的上下文当中。而
ContextBoundObject
的子类所建立的对象只能在建立它的对应上下文中正常运行,此状态被称为上下文绑定。其他对象想要访问ContextBoundObject
的子类对象时,都只能通过代透明理来操作。

上下文可以看作应用程序域中一个包含对象和消息接收器的区域。对上下文里的对象的调用会转换成可以被MessageSink(消息接收器)拦截和处理的消息。我们知道要把调用转换成消息,必须通过透明代理这个中介。而且,仅当对象是MarshalByRefObject的子类的实例并被其所在的应用程序域以外的实体调用时,CLR才会为它创建透明代理。这里,我们希望对所有调用使用消息接收器机制,即使那些调用是来自同一个应用程序域中的实体。这个时候我们就需要用到System.ContextBoundObject类了。继承自ContextBoundObject的类的实例同样仅能由透明代理访问。此时,即使在这个类的方法中使用的this引用也是透明代理而不是对这个对象的直接引用。我们会发现ContextBoundObject类继承自MarshalByRefObject,这非常合理,因为它很好地强调了该类的特性——它告诉CLR这个类将会通过透明代理使用。

ContextBoundObject的子类的实例被视为上下文绑定的(context-bound)。没有继承自ContextBoundObject的类的实例则被视为上下文灵活的(context-agile)。上下文绑定的对象永远在其上下文中执行。只要不是远程对象,上下文灵活的对象总是在执行这个调用的上下文中执行。您可以在任何 ContextBoundObject 上使用SynchronizationAttribute来同步所有实例方法和字段。同一上下文域中的所有对象共享同一锁。允许多个线程访问方法和字段,但一次只允许一个线程。

将System.Runtime.Remoting.Contexts.SynchronizationAttribute应用于某个类后,该类的实例无法被多个线程同时访问。我们说,这样的类是线程安全的。

应用

使用SynchronizationAttribute和ContextBoundObject一起组合创建一个简单的自动的同步。
该对象内部构成一个同步域。只允许一个线程进入。
将 SynchronizationAttribute应用于某个类后,该类的实例无法被多个线程同时访问。我们说,这样的类是线程安全的。
该方式实现的同步已经过时,只做了解。

using System;
using System.Threading;
using System.Runtime.Remoting.Contexts; [Synchronization]//如果[Synchronization(ture)]就表示允许线程重入 ,这样容易引发死锁
public class AutoLock : ContextBoundObject
{
public void Demo()
{
Console.Write ("Start...");
Thread.Sleep (1000); // We can't be preempted here
Console.WriteLine ("end"); // thanks to automatic locking!
}
} public class Test
{
public static void Main()
{
AutoLock safeInstance = new AutoLock();
new Thread (safeInstance.Demo).Start(); // Call the Demo
new Thread (safeInstance.Demo).Start(); // method 3 times
safeInstance.Demo(); // concurrently.
}
}
//输出:
//Start... end
//Start... end
//Start... end

【MSDN:将 SynchronizationAttribute 应用到一个上下文绑定对象会导致创建等待句柄和自动重置事件,这些内容不一定会被作为垃圾来回收。因此,不要在很短的时间内创建大量用 SynchronizationAttribute 标记的上下文绑定对象。】

原因就是整个对象都是一个锁,就是在thread1没处理完,其他线程是无法进行操作的。

CLR确保一次只有一个线程可以执行其中的代码。它通过创建一个同步对象来实现这一点——并在每个方法或属性的每次调用时锁定它。锁的作用域——在本例中同步对象——被称为同步上下文。safeinstancesafeinstance
那么,这是如何工作的呢?一个线索在属性的命名空间:。A可以被认为是一个“远程”对象,这意味着所有的方法调用都被拦截。为了使这种拦截成为可能,当我们实例化时,CLR实际上返回一个代理——一个具有与对象相同的方法和属性的对象,它充当中介。自动锁定就是通过这个中介发生的。总的来说,拦截在每个方法调用上增加了大约一微秒。。。点击查看内容来源

同步域

.NET同步域(Synchronization特性)

同步域的概念是来源于多线程的场合,在我们进行多线程操作的时候,让很多个线程去同时访问一个内存对象的时候,是必须用锁来保证只有一个线程进入对象操作的,那么同步域的概念就是同步的是一个区域,而不是单单的一个对象。

上面的例子中对象的内部就形成一个同步域,只允许一个线程进入。

【C# 线程】ContextBoundObject类 --上下文绑定 和SynchronizationAttribute属性 、同步域的更多相关文章

  1. 【C#】【Thread】上下文同步域SynchronizationAttribute

    上下文同步:使用SynchronizationAttribute为ContextBoundObject对象创建一个简单的自动的同步. 这种同步方式仅用于实例化的方法和域的同步.所有在同一个上下文域的对 ...

  2. Ninject之旅之九:Ninject上下文绑定(附程序下载)

    摘要 既然在插件模型里,每一个服务类型可以被映射到多个实现,绑定方法不用决定要返回哪个实现.因为kernel应该返回所有的实现.然而,上下文绑定是多个绑定场景,在这个场景里,kernel需要根据给定的 ...

  3. 『TensorFlow』线程控制器类&变量作用域

    线程控制器类 线程控制器原理: 监视tensorflow所有后台线程,有异常出现(主要是越界,资源循环完了)时,其should_stop方法就会返回True,而它的request_stop方法则用于要 ...

  4. 线程 ManualResetEvent 类

    Reset(): 当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时, 它调用 Reset 以将 ManualResetEvent 置于非终止状态.此线程可被视为控制 ManualRese ...

  5. FreeOnTerminate 的线程在线程管理类的Destroy释放时手工释放的问题

    这个问题折腾了我整整一天. 有一个线程管理类,集中管理所有新建的线程, 线程统一在创建时标识 FreeOnTerminate 为 True. 因为有的线程是不限次循环的,所以在管理类最后 Destro ...

  6. WPF——传实体类及绑定实体类属性

    public class User: private string _User; public string User1 { get { return _User; } set { _User = v ...

  7. Qt 学习之路 :Qt 线程相关类

    希望上一章有关事件循环的内容还没有把你绕晕.本章将重新回到有关线程的相关内容上面来.在前面的章节我们了解了有关QThread类的简单使用.不过,Qt 提供的有关线程的类可不那么简单,否则的话我们也没必 ...

  8. C#中假设正确使用线程Task类和Thread类

    C#中使用线程Task类和Thread类小结 刚接触C#3个月左右.原先一直使用C++开发.由于公司的须要,所地採用C#开发.主要是控制设备的实时性操作,此为背景. 对于C#中的Task和Thread ...

  9. 工作线程基类TaskSvc

    工作线程基类TaskSvc 前端时间用ACE写代码,发ACE_Task确实好用.不但能提供数量一定的线程,还能够让这些继承的线程函数自由访问子类的private和protected变量.此外,ACE_ ...

随机推荐

  1. CMake语法—缓存变量(Cache Variable)

    目录 CMake语法-缓存变量(Cache Variable) 1 CMake缓存变量 2 定义缓存变量 2.1 定义格式 2.2 定义示例代码 2.3 运行结果 2.4 小结 3 CMakeCach ...

  2. kubernetes之部署dashboard 和heapster

    部署dashboard之前,先确保traefik https方式部署成功,这样就可以通过 https 域名的方式访问dashboard,无需kube-proxy转发了.假设traefik-ingres ...

  3. JVM专题1: 类和类加载机制

    合集目录 JVM专题1: 类和类加载机制 Java对象的结构 在HotSpot虚拟机中, 对象在内存中存储的布局可以分为3块区域 对象头Header 实例数据Instance Data 对齐填充Pad ...

  4. python 小兵(8)闭包和装饰器

    闭包"是什么,以及,更重要的是,写"闭包"有什么用处. (个人理解) 1."闭包"是什么 首先给出闭包函数的必要条件: 闭包函数必须返回一个函数对象 ...

  5. java 变量的定义 类型转换 基本的数据类型

    package com.aaa.zxf.ajax.test; import org.junit.Test; /** * 六. * 如何在ideal的maven项目中导入 Test 测试类? * * * ...

  6. UIImageView的序列帧动画

    #pragma mark - 开始动画 - (IBAction)startAnimation { // 1.1 加载所有的图片 NSMutableArray<UIImage *> *ima ...

  7. java中的成员变量和局部变量的区别

    成员变量: 在类体里面定义的变量叫做成员变量: 如果在变量有static关键字修饰,就叫作静态变量或类变量: 如果该变量没有static关键字修饰,就叫作非静态变量或实例变量: 局部变量: 方法内定义 ...

  8. 基于GDAL库海洋表温日平均计算工具设计与实现 C++版

    技术背景 在对物理海洋数据处理过程中,表层温度是众多要素中的一种,本文书要是针对海洋表温数据批量日平均处理的一个工具设计.首先要在对当前的SST数据文件作一下简要的说明,SST全称为sea surfe ...

  9. 微服务从代码到k8s部署应有尽有系列(二、网关)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  10. .NET官方封装的Win32API类库

    大部分朋友在使用C#.NET调用Win32API时都不清楚API函数的声明,要么就是抄网上的代码,但是总会遇到各种各样奇奇怪怪难以解决的问题,打算自己封装又发现工作量实在太大. 其实完全没有必要自己动 ...