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. VS2017:win32项目与win32控制台应用程序的转换方法

    原文:https://www.cnblogs.com/asuser/articles/12297251.html 刚开始使用VS2017新建项目工程时,有时把应用类型的工程建成控制台类型的工程,在编译 ...

  2. gin中如何自定义验证器

    package main import ( "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding&qu ...

  3. 集合框架-工具类-JDK5.0特性-ForEach循环

    1 package cn.itcast.p4.news.demo; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 impo ...

  4. ansible lineinfile 关闭selinux

  5. Web安全防护(二)

    点击劫持 点击劫持,也称UI覆盖攻击 1.1 iframe覆盖攻击 黑客创建一个网页,用iframe包含了目标网站,并且把它隐藏起来.做一个伪装的页面或图片盖上去,且按钮与目标网站一致,诱导用户去点击 ...

  6. 强化学习实战 | 自定义Gym环境之扫雷

    开始之前 先考虑几个问题: Q1:如何展开无雷区? Q2:如何计算格子的提示数? Q3:如何表示扫雷游戏的状态? A1:可以使用递归函数,或是堆栈. A2:一般的做法是,需要打开某格子时,再去统计周围 ...

  7. K8s QoS Pod资源服务质量控制

    Kubernetes 中如果一个 Node 节点上的 Pod 占用资源过多并且不断飙升导致 Node 节点资源不足,可能会导致为了保证节点可用,将容器被杀掉.在遇见这种情况时候,我们希望先杀掉那些不太 ...

  8. [源码解析] 分布式训练Megatron (1) --- 论文 & 基础

    [源码解析] 分布式训练Megatron (1) --- 论文 & 基础 目录 [源码解析] 分布式训练Megatron (1) --- 论文 & 基础 0x00 摘要 0x01 In ...

  9. 『无为则无心』Python基础 — 42、Python中文件的读写操作(二)

    目录 (5)文件对象方法(重点) 1)写方法 2)读方法 3)seek()方法 4)tell()方法 (6)关闭 (7)综合练习:读取大文件 (5)文件对象方法(重点) 1)写方法 @1.语法 对象对 ...

  10. RabbitMQ如何实现延迟队列?(转)

    什么是延迟队列 延迟队列存储的对象肯定是对应的延迟消息,所谓"延迟消息"是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 场景一 ...