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. vue学习10-计算属性

    计算属性 1 <!DOCTYPE html> 2 <html lang='en'> 3 <head> 4 <meta charset='UTF-8'> ...

  2. ARTS Week 22

    Algorithm 本周的 LeetCode 题目为 297. 二叉树的序列化与反序列化 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也 ...

  3. java内部类细节

    1 package face_09; 2 /* 3 * 为什么内部类能直接访问外部类中的成员呢? 4 * 那是因为内部类持有了外部类的引用. 外部类名.this 5 * 6 */ 7 class Ou ...

  4. 集合框架-工具类-JDK5.0特性-函数可变参数

    1 package cn.itcast.p4.news.demo; 2 3 public class ParamterDemo { 4 5 public static void main(String ...

  5. python15day

    昨日回顾 装饰器:完美的呈现了开放封闭原则.本质:闭包. def wrapper(f): def inner(*args,**kwargs): '''在执行被装饰函数之前,想写什么代码写什么代码''' ...

  6. Java线上问题排查神器Arthas实战分析

    概述 背景 是不是在实际开发工作当中经常碰到自己写的代码在开发.测试环境行云流水稳得一笔,可一到线上就经常不是缺这个就是少那个反正就是一顿报错抽风似的,线上调试代码又很麻烦,让人头疼得抓狂:而且deb ...

  7. makefile快速入门

    前言 在linux上开发c/c++代码,基本都会使用make和makefile作为编译工具.我们也可以选择cmake或qmake来代替,不过它们只负责生成makefile,最终用来进行编译的依然是ma ...

  8. C++的set重载运算符

    转载: https://www.cnblogs.com/zhihaospace/p/12843802.html set 容器模版需要3个泛型参数,如下: template<class T, cl ...

  9. 2020-11-21 f

    题意:给定一个长度为 \(n\) 的序列 \(A\),\(A_i \in [0, 2 ^ k)\).定义 \(f(x)\) 为 \(A_1\) ^ \(x\),\(A_2\) ^ \(x \cdots ...

  10. Jvm和CPU保证特定情况下不乱序

    简介 CPU为了提高指令执行效率,会在一条指令执行过程中(比去内存读数据(慢100倍)),去同时执行另一条指令,前提是,两条指令没有依赖关系. CPU保证不乱序 MESI--CPU缓存一致性协议(In ...