.NET简谈组件程序设计之(上下文与同步域)

我们继续学习.NET多线程技术,这篇文章的内容可能有点复杂。在打破常理之后,换一种新的思考模型最为头疼。这篇文章里面会涉及到一些不太常见的概念,比如:上下文、同步域等等。我也是最近才接触这些关于组件编程方面的高深技术,大家一起学习,再大的困难也是有时间限制的,只要我们坚持。

在本人的上一篇文章“.NET简谈组件程序设计之(多线程与并发管理一)”中,只是初步的带领我们学习一下关于多线程的一些基本的原理,包括线程切换,线程的开始、执行、等待、结束。

这篇文章的重点是学习关于线程的同步、互斥的机制。在多线程的应用程序中,最少会有一个主线程在运行着,如果我们想提高应用程序的吞吐量就必须借助多线程的原理来实现。[王清培版权所有,转载请给出署名]

.NET上下文(ContextBoundObject对象)

什么叫上下文,千万别和ASP.NET中的上下文搞混了,这个上下文是个形容词,在不同的场合有不同的意思。在ASP.NET中的上下文是指Context对象,这个对象基本上包容了HTTP协议的整个生命周期的信息,可以获取到客户端浏览器的一些基本信息,也可以获取到关于HTTP协议的一些信息,等等。

这里所讲的上下文是.NET程序执行的最小逻辑范围,ASP.NET上下文是站在B/S编程模型角度去看待的,而这里的上下文是站在.NET底层运行角度看来的,后者是代码的上下文,前者是整个生命周期的上下文。

在没有接触ContextBoundObject之前我一直以为.NET程序执行的最小逻辑范围是应用程序域(AppDomain),知道了之后才知道另有隐情,上下文是用来确定对象的逻辑归属,在多线程(Thread)、事物处理(Transaction)、企业服务(Enterprise)等方面都需要用上下文来对对象进行规划。下面您将看到怎么用上下文来进行线程的同步的。

图1:

.NET同步域(Synchronization特性)

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

线程是代码的执行路径,只要在这条执行路径上都属于线程的范围,那么怎么在执行的路径中分离出另外一个同步区域。[王清培版权所有,转载请给出署名]

临界资源是系统中对同一时间只能由一个线程进行访问的描述。我们假设自己就是一个线程,我们要去家里拿点东西,那么门就是线程的同步锁,当我们进去的时候就把门从里面反锁,出去的时候就把门打开,以方便自己的家人进来。这个房子就是临界资源。可能这样的描述不太靠谱,哪有这样的家啊!

图2:

利用上下文和同步域进行线程的同步

下面我们将结合上下文和同步域的原理进行线程的同步。请看一段代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Contexts;
namespace ConsoleApplication1.多线程和并发管理
{
    //如果不加上下文,那么就是以对象为线程锁定区域,如果加上下文,那么就是已逻辑上下文为锁定区域
    [Synchronization(SynchronizationAttribute.REQUIRED, true)]//重新进入同步域
    public class MyClass : ContextBoundObject
    {
        public void DoWork()
        {
            int i = 0;
            while (true)
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "|" + i++);
                if (i == 10)
                {
                    Console.WriteLine("---------------------------------------------");
                    Console.Read();
                    break;
                }
            }
        }
    }
}

 

在这段代码里面,我给Myclass类加上了Synchronization特性,并且继承自上下文对象ContextBoundObject。两者必须集合使用,同步域只有在上下文中才有效。

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

图3:

图4:

我们来看调用代码:

Thread currentthread = Thread.CurrentThread;
Console.WriteLine(currentthread.Name + currentthread.ManagedThreadId);
MyClass myclass = new MyClass();
Thread thread = new Thread(new ThreadStart(myclass.DoWork));
Thread thread2 = new Thread(new ThreadStart(myclass.DoWork));
thread2.Start();
thread.Start();
thread2.Join();
thread.Join();
Console.WriteLine(currentthread.Name + currentthread.ManagedThreadId);
Console.Read();

 

图5:

我为了方便截图所以把循环的数字设的比较小,如果你想测试一下,可以把数字设的大一点。[王清培版权所有,转载请给出署名]

在SynchronizationAttribute对象里面有几个枚举值,是用来确定是否共享一个同步域的,有兴趣的可以自己尝试,我就不在这里多讲了。

总结:同步域和上下文对象是线程自动同步的好方法,但是他锁定的目标太大,难免导致系统的吞吐量下降,所以下面几篇文章我们将会学习怎么使用手动同步来实现更灵活的同步(Monitor、WaitHandler等),从很小的粒度进行锁定。

时间: 2024-10-04 12:01:19

.NET简谈组件程序设计之(上下文与同步域)的相关文章

.NET简谈组件程序设计之(手动同步)

在上一篇文章".NET简谈组件程序设计之(上下文与同步域)"中,我们学习了关于一些上下文和同步域的概念,可以利用这两个技术来进行自动同步. 今天我们主要学习怎么手动来执行同步,能从更小的粒度进行封锁,以达到最大程度的吞吐量.[王清培版权所有,转载请给出署名] 我们知道线程是进程的运行实体,进程是资源分配单位,而线程是执行单位.照书上所说,线程是程序的执行路径,当我们分配一个线程的时候,要确定线程的执行路径是什么,也就是代码中的ThreadStart委托所指向的入口点方法. 一旦我们手动

.NET简谈组件程序设计之(初识.NET线程Thread)

由于多线程的内容比较多我会用几篇文章来讲解. 多线程在我们日常开发过程中用的很多,上一篇".NET简谈组件程序设计之(异步委托) "详细的讲解了基于委托的多线程使用,委托是基于后台线程池的原理,这篇文章将主要介绍直接使用Thread对象来实现多线程. 当然使用Thread没有使用Delegate那么容易,毕竟多线程跟异步调用是两个相差很大的技术方向,我也是略懂点皮毛,在此献丑给大家,如有讲的不对的地方还请指出.[王清培版权所有,转载请给出署名] 我们先来理解几个概念,以方便我们学习.

.NET简谈组件程序设计之(初识远程调用)

在.NET1.0版本出来的时候,要想进行远程调用基本上都是通过WebService的方式.而随着.NET2.0版本的出现,我们可以通过一个更加方便且高扩展性的框架来进行编写远程调用的程序,也就是我们都比较熟悉的.NetRemoting. 网上对.NetRemoting技术讲解的文章不计其数,但是很少有一本比较全面的.系统的学习书籍.我们都是从哪些零散的知识里慢慢摸索,效果不太理想. 今天我也来简单的介绍一下我理解的Remoting.不仔细研究一下还真不知道它的厉害,完全的托管平台.高扩展性.灵活

.NET简谈组件程序设计之(渗入序列化过程)

在本人的上一篇文章".NET简谈组件程序设计之(初识序列化.持久化) "中,我们基本上了解了什么叫序列化和持久化.通过系统为我们提供的服务,我们可以很方便的进行二进制序列化.SOAP协议序列化. 今天这篇文章是来讲解怎么运用一些高级的功能,在序列化.反序列化过程中进行一些控制.[王清培版权所有,转载请给出署名] 这里穿插一句题外话:其实在我们自己编写组件的时候真的有好多东西可以借鉴.NET平台的一些优点,它的功能都不是死的,可以订阅.可以切入,在我们编写组件的时候,我们其实也要好好考虑

.NET简谈组件程序设计之(初识NetRemoting)

在本人的".NET简谈组件程序设计之(初识远程调用)  "一文中,我们了解到什么是远程调用或者说在.NET平台上远程调用是什么样子的,可能和偏低层(Socket\Rpc)的远程调用有点距离.这只是系统为我们封装了假象而已,看不见不代表没有这逻辑,是为我们减轻了劳动负担.[王清培版权所有,转载请给出署名] 这篇文章我们来简单的了解一下在.NET平台上有一个强有力的远程调用武器,也是上一篇文章中我一笔带过的远程英雄.NetRemoting. 其实在.NET平台里面到处都能看见Remotin

.NET简谈组件程序设计之(delegate与event关系)

 本人最近一段时间在学习关于.NET组件编程方面的技术,在学习过程中确实有很多好的东西需要与大家分享.[王清培版权所有,转载请给出署名] 关于什么叫组件编程,其实就是利用.NET来开发基于组件模型的程序,面向组件编程而非面向对象编程,这是一个高度,没有很长时间的学习与磨练 是体会不到这个感觉的.我们现在的开发思想应该是以面向对象为主的,但是如何提升这个高度,只有慢慢的学习了. 其实面向组件编程包含了面向对象编程思想,将一组功能独立的封装起来供以后重复使用,但是在开发组件的过程中需要使用到面向对象

.NET简谈组件程序设计之(初识序列化、持久化)

 今天我们来学习在组件开发中经常用到的也是比较重要的技术"序列化". 序列化这个名词对初学者来说不太容易理解,有点抽象.我们还是用传统的分词解释吧,肯定能搞懂它的用意是什么. 解释:数学上,序列是被排成一列的对象(或事件):这样,每个元素不是在其他元素之前,就是在其他元素之后.这里,元素之间的顺序非常重要. 那么我们对照这样的解释来分析一下我们程序中的序列化什么意思.都知道对象的状态是在内存中实时存着的,对象的状态在初始化的时候是通过系统分配的,在后期的程序运行过程中可能对它进行过一些

.NET简谈组件程序设计之(详解NetRemoting结构)

在本人的上一篇文章中只是简单的介绍了一下.NETRemoting的一般概念和基本的使用.这篇文章我想通过自己的学习和理解将对.NETRemoting的整体的一个框架进行通俗的讲解,其中最重要的就是信道(管道)处理模型思想,这里面蕴含了很多的设计原理.[王清培版权所有,转载请给出署名].NETRemoting远程处理架构是一个半成品,是.NET给我们的扩展框架,要想用于商业项目必须进行一些安全.性能方面的控制.要想进行一定深度的扩展那就要必须了解它的整体结构,各个点之间的关系才能很好的控制它. 网

.NET简谈组件程序设计之(AppDomain应用程序域)

最近在苦学.NET底层框架模型,发现.NET深入真的不是一般的难,不开源.没有相关系统的官方的书籍做学习资料,只能零散的看MSDN.要想摸熟.NET的模型真的并非易事.慢慢来吧.[王清培版权所有,转载请给出署名] .NET应用程序域(AppDomain)是我们所有.NET应用程序的逻辑宿主容器.初次接触会感觉到AppDomain离我们日常开发比较远,不常用到.其实是我们很少接触一些复杂而底层的系统结构.在日常的开发中,我们多数是基于数据库的管理信息系统(MIS),做增.删.改.查的操作.我始终认