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. 论文解读《The Emerging Field of Signal Processing on Graphs》

    感悟 看完图卷积一代.二代,深感图卷积的强大,刚开始接触图卷积的时候完全不懂为什么要使用拉普拉斯矩阵( $L=D-W$),主要是其背后的物理意义.通过借鉴前辈们的论文.博客.评论逐渐对图卷积有了一定的 ...

  2. MySQL的MyISAM与InnoDB的索引方式

    在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 MyISAM引擎使用B+Tr ...

  3. default和delete

    在C++中,有四类特殊的成员函数,分别为:默认构造函数,默认析构函数,默认拷贝构造函数,默认赋值运算符.他们的作用为创建.初始化.销毁.拷贝对象. 虽然在类A中什么都没有定义,但是编译会通得过,因为编 ...

  4. Ioc容器-Bean管理(工厂bean)

    IoC操作Bean管理(FactoryBean) 1,Spring有两种类型bean,一种像自己创建的普通bean,另一种工厂bean(FactoryBean) 2,普通bean:在spring配置文 ...

  5. APC 篇——备用 APC 队列

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  6. 从容器中获取宿主机IP地址

    背景: docker 中的程序需要连接外部的程序,连接的过程中会告知外部程序自己的ip地址,然后外部的程序会回连docker中的程序.由于docker使用的是rancher中的托管模式,外部程序是没办 ...

  7. 海康NVR设备上传人脸图片到人脸库

    海康开放平台--海康文档链接--海康开发包和文档下载链接 硬件:海康超脑NVR(全称Network Video Recorder,即网络视频录像机).人脸摄像机. 环境:JDK_1.8 Windows ...

  8. 【第十二期】腾讯后台实习初试、复试、HR面经 (许愿OC)

    楼主投的很晚属于正常批才开始,初试面试官比较重基础,复试面试官比较看综合能力,HR小姐姐声音好听,腾讯面试官都特别nice! 一面: 看你项目很多,你挨个给我介绍一遍吧 我:一大堆按着简历介绍 日志文 ...

  9. 【微服务】- SpringCloud中Config、Bus和Stream

    文章目录 SpringCloud中Config 1.Config的简介 官网 分布式系统面临的问题 config是什么 如何使用 能做什么 与git的配合使用 2.Config服务端的配置和测试 准备 ...

  10. linux中shell变量$#等的释义

    linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: 1. $$ Shell本身的PID(ProcessID) 2. $! Shell最后运行的后台Process的PID 3 ...