雁过请留痕...
代码改变世界

随笔分类 -  .Net

基元线程同步——Interlocked Anything模式

2012-08-29 14:19 by xiashengwang, 964 阅读, 收藏, 编辑
摘要: 上一篇基元线程同步——基础,非阻塞同步(VolatileRead,VolatileWrite,volatile,Interlocked)已经对Interlocked类做了比较详细的分析,这一篇是对Interlocked类的一个模式进行补充说明。如果没用过Interlocked类,可以看看上面的这篇文章。这个模式的名字是Jeffrey给起的,它究竟要解决什么问题,我们为什么要用它?带着这些疑问,我们来看看它的应用场景。看看下面这个设定最大值的例子: private static Int32 Maximum(ref int target, int value) { ... 阅读全文

基元线程同步——基础,非阻塞同步(VolatileRead,VolatileWrite,volatile,Interlocked)

2012-08-25 11:22 by xiashengwang, 4015 阅读, 收藏, 编辑
摘要: 一、基元用户模式和内核模式。基元(Primitive):指代码中可以使用的最简单的构造。有两种基元构造:用户模式(user-mode)和内核模式(kernel-mode)。1,用户模式。它是用CPU指令来协调线程,这种协调是在硬件中发生的,所以速度会快于内核模式。但是也意味着,Windows操作系统永远也检测不到一个线程在一个基元用户模式构造上阻塞了。由于在一个基元用户模式构造上阻塞的线程永远不认为已经阻塞,所以线程池不会创建新的线程来替换这种阻塞的线程。另外,这些CPU指令只是阻塞线程极短的时间。缺点:只有Windows系统的内核才能停止一个线程的执行。用户模式中的线程可能会被系统抢占,但很 阅读全文

线程同步——优势、劣势

2012-08-25 10:16 by xiashengwang, 813 阅读, 收藏, 编辑
摘要: 一、线程同步好处:多个线程同时访问共享数据时,防止数据被损坏。二、线程同步带来的问题:1,实现比较繁琐,而且容易出错。必须对多个线程可能同时访问的所有数据,用额外的代码包围起来,以获得和释放一个同步锁。这需要由程序员来保证没有遗漏,对多线程共享的数据的加锁工作。并且,在程序完成时,需要进行压力测试以保证多个线程并发时,结果如预期。2,它会损害性能。获取和释放一个锁是需要时间的。因为需要额外的调用一些方法,并且需要协调调度下一个获得锁的线程。3,每次只能允许一个线程访问资源。这是锁的全部意义所在,但也是问题所在,因为阻塞一个线程可能会造成更多的线程被创建。三、线程同步建议:1,线程同步并不是一件 阅读全文

研究BackgroundWorker后发现:AsyncOperation和SynchronizationContext的差异真的很大!

2012-08-22 15:58 by xiashengwang, 1609 阅读, 收藏, 编辑
摘要: 今天研究BackgroundWorker代码时发现,两处代码的写法有些不一致,于是好奇的测试了一番,以为能测出BackgroundWorker的一个bug。结果大家都知道microsoft胜了。下面来看看过程,BackgroundWorker类里的ReportProgress方法public void ReportProgress(int percentProgress, object userState){if (!this.WorkerReportsProgress) throw new InvalidOperationException("BackgroundWorker_Wo 阅读全文

APM异步编程模型的优势

2012-08-21 14:11 by xiashengwang, 1271 阅读, 收藏, 编辑
摘要: 我们之所以要花大力气学习APM,就必须要清楚它能解决实际编程中的那些难题。以及现有的技术为什么不行。简单点说:APM是基于IAsyncResult接口的,采用的BeginXXX和EndXXX的形式来实现异步。下面这几点就是APM的优势:1,线程执行是异步的,不会阻塞调用线程。这一点也是我们使用异步的主要目的,我们不就是希望后台处理一些耗时操作吗?2,任务完成可以得到通知。(非阻塞)3,任务可以实现进度报告。(需要额外的辅助代码支持)4,可以有返回值。5,参数可以是多个。再看看Thread,ThreadPool,Task能实现上面的几点?这三个中,Task是相对完善的一个,对于第2点它可以通过C 阅读全文

定时器Timer的选择

2012-08-18 18:20 by xiashengwang, 511 阅读, 收藏, 编辑
摘要: FCL提供了好几个Timer供我们选择,但却让很多人分不清他们的使用场合。下面来总结一下:System.Threading的Timer类。要在线程池上定时执行后台任务,他就是就好的选择。System.Windows.Forms的Timer类。这个类可以通过Vs的设计界面拖拽,它和UI线程是相关的,它使用的就是UI线程,所以在这里面执行UI更新的操作不会报线程非法访问的错。但是,如果在定时执行的函数里有长时间的运行任务,则会阻塞UI线程,造成界面”假死“。System.Windows.Threading的DispatcherTimer类。这个是System.Windows.Forms的Timer 阅读全文

线程阶段性总结——APM,ThreadPool,Task,TaskScheduler ,CancellationTokenSource

2012-08-18 16:39 by xiashengwang, 2450 阅读, 收藏, 编辑
摘要: 不管我们使用thread,threadPool,task,还是APM异步,本质都是在使用多线程。对于新手来说,不太敢用多线程的原因,就我个人的体验来说,就是对多线程的异常捕获方式或时机缺乏了解,而一旦出现异常没有捕获,将会带来难以发现的bug,进而造成系统崩溃。而多线程本身也不是一朝一夕就能学好的,必须不断的去学习总结,所以我个人认为你要用一种线程模型,首先要对它有足够的了解,特别是对异常的捕获。如果你没有完全的把握,最好在实际开发中谨慎的用多线程。1,APM异步编程模型。采用BeginXXX和EndXXX方法。关于异常的捕捉,对于刚调用BeginXXX抛出的异常,异步操作可能还没有进入队列。 阅读全文

颜色分段显示,线性填充的一个Demo

2012-08-02 17:51 by xiashengwang, 1747 阅读, 收藏, 编辑
摘要: 1,指定一个开始颜色,一个结束颜色,进行填充。2,生成指定数量的,这两个颜色中间的过渡色,这个对地图表示等功能需要分段颜色表示的很有用。效果图:先看第一个功能,填充渐变的颜色:主要就是利用LinearGradientBrush这个画刷 lblStartColor.Click += new EventHandler(lblColor_Click); lblEndColor.Click += new EventHandler(lblColor_Click); void lblColor_Click(object sender, EventA... 阅读全文

GC垃圾回收——有用的函数和类

2012-08-01 16:10 by xiashengwang, 5532 阅读, 收藏, 编辑
摘要: 1,AddMemoryPressure和RemoveMemoryPressure 这两个方法主要用于本地资源,比如一个位图占用了50M本地内存,但是托管对象只包含一个HBitMap(4字节或8字节)。但CRL并不知道这个内存压力,它可能允许你分配数百个位图,因为它们占用的托管内存太少了。这两个方法的目的就是要告诉GC它实际的本地资源用了多少内存量,GC知道这个信息后会调整它的垃圾回收策略,当压力变大时,他就强制执行垃圾回收。 private void MemoryPressureDemo(int size) { //创建一组对象,并指定它们的... 阅读全文

《CLR via C#》笔记——垃圾回收

2012-07-31 20:58 by xiashengwang, 1262 阅读, 收藏, 编辑
摘要: 本篇目录1,垃圾回收的基本概念 1.1 小对象堆和大对象堆 1.2 垃圾回收中的“代” 1.3 堆和“代”的关系2,啥时执行垃圾回收?3,垃圾回收器是如何工作的? 3.1标记无效对象。 3.2 压缩阶段。 3.3 终结揭秘4 ,Dispose模式:强制对象清理资源1,垃圾回收的基本概念1.1 小对象堆和大对象堆 我们都知道,CLR将我们的引用类型分配到托管堆上。这里指的托管堆实际是一个笼统的称呼。它实际是由一个小对象堆(small object heap,SOH)和一个大对象堆(large object heap,LOH)组成的。为对象分配空间时,将对象分为小对象(small object). 阅读全文

《CLR via C#》笔记——异常和状态管理

2012-07-30 12:48 by xiashengwang, 2797 阅读, 收藏, 编辑
摘要: 目录一,定义异常二,异常处理机制 2.1 try块 2.2 catch块 2.3 finally块 2.4 CLS和非CLR异常三,System.Exception类四,抛出异常五,自定义异常类六,用可靠性换取开发效率七,指导原则和最佳实践 7.1 善用finally块 7.2 不要什么都捕捉 7.3 得体的从异常中恢复 7.4 从不可恢复的异常中回滚——维持状态 7.5 隐藏实现细节来维持契约八,未处理异常九,约束执行区(CER)十,代码契约一,定义异常 什么时候应该抛异常?当一个类型的成员(如方法,属性)不能完成任务时,就应抛出异常。面向对象的编程大大... 阅读全文

《CLR via C#》笔记——可空值类型

2012-07-20 18:15 by xiashengwang, 457 阅读, 收藏, 编辑
摘要: 一,可空值类型 顾名思义,这种类型支持null值。在FCL中被定义为System.Nullable类型。这是一个结构体类型(struct),所以,不要认为System.Nullable是一个引用类型,它仍然是一个值类型。要使用可空值类型,在代码中可以这样写: Nullable x = 10; Nullable y = null; Console.WriteLine("x: HasValue={0} Value={1}", x.HasValue, x.Value); Console.WriteLine("y:... 阅读全文

《CLR via C#》笔记——线程基础

2012-07-20 14:22 by xiashengwang, 1400 阅读, 收藏, 编辑
摘要: 一,Windows为什么要支持线程 进程(process)是应用程序的一个实例要使用的资源的一个集合。每个进程都有一个虚拟化的地址空间,确保一个进程的代码不会被另外一个进程访问,这确保了应用程序的健壮性和安全性。但当应用程序执行一个无限循环,系统中又只有一个CPU时,他会执行无限循环,不能执行其他东西。为此,Mircorsoft引入了线程。线程(thread)的职责就是对CPU进行虚拟化,Windows为每个进程提供了该进程专用的线程。如果应用程序进入无限循环,与代码相关的进程会被“冻结”,但其他进程可以继续执行。二,线程开销线程会产生空间和时间上的开销。每个线程都包含以下要素:●线程内核对象 阅读全文

《CLR via C#》笔记——运行时序列化(3)

2012-07-18 20:54 by xiashengwang, 942 阅读, 收藏, 编辑
摘要: 七,流上下文 前面讲过,一组序列化好的对象可以有许多的目的地;同一进程,同一台机器的不同进程,不同机器的不同进程等。在一些比较少见的情况下,一个对象可能想知道他要在什么地方被反序列化,从而以不同的方式生成它的状态。例如:一个包装了Windows信号量(semaphore)的一个对象,如果它知道反序列化到同一个进程中,就可能决定序列化它的内核句柄(kernel handle),这是因为内核句柄在同一进程中有效。然而,如果它知道要反序列化到同一机器的不同进程中,就可能对信号量的字符串名称进行序列化。最后,如果对象知道它要反序列化到一台不同的机器上的一个进程中,就可能抛出异常,因为信号量值在同一台机 阅读全文

《CLR via C#》笔记——运行时序列化(2)

2012-07-18 20:52 by xiashengwang, 1422 阅读, 收藏, 编辑
摘要: 五,格式化器如何序列化类型实例为了简化格式化的操作,FCL在System.Runtime.Serialization命名空间提供了一个FormatterServices类型。该类型只包含静态方法,而且不能被实例化。以下的步骤描述了格式化器如何自动序列化一个应用了SerializableAttribute的对象。1,格式化器调用FormatterServices的GetSerializableMembers方法:public static MemberInfo[] GetSerializableMembers(Type type,StreamingContext context)这个方法利用反射 阅读全文

《CLR via C#》笔记——运行时序列化(1)

2012-07-18 20:43 by xiashengwang, 1069 阅读, 收藏, 编辑
摘要: 一,运行时序列化的作用序列化(Serialization)是将一个对象转换成一个字节流的过程。反序列化(Deserialization)是将一个字节流转换回一个对象的过程。在对象和字节流之间的转化是非常有用的机制。下面是一些例子。●应用程序的状态可以轻松保存到一个磁盘或数据库中,并在应用程序下次运行时恢复。Asp.net就是利用序列化和反序列化来保存和恢复会话状态的。●一组对象可轻松复制到剪贴板,在粘贴回同一个或另一个应用程序。事实上,Windows窗体和WPF就是利用了这个功能。●一组对象可以克隆放到一边作为“备份”;与此同时,用户操纵一组“主”对象。●一组对象可轻松地通过网络发给另一台机器 阅读全文

《CLR via C#》笔记——AppDomain(2)

2012-07-17 09:22 by xiashengwang, 2224 阅读, 收藏, 编辑
摘要: 四,卸载AppDomain AppDomain很出色的一个能力就是它允许卸载。卸载AppDomain会导致CLR卸载AppDomain中的所有程序集,还会释放AppDomain的Loader堆。为了卸载一个AppDomain,可以调用AppDomain的静态方法UnLoad,这将导致CLR执行一系列的操作来卸载AppDomain。1,CLR挂起进程中执行过托管代码的所有线程。2,CLR检查所有线程栈,查看哪些线程正在执行要卸载的那个AppDomain中的代码,或者哪些线程会在某个时候返回至要卸载的那个AppDomain。在任何一个栈上,如果有准备卸载的AppDomain,CLR都会强迫对应的线 阅读全文

《CLR via C#》笔记——AppDomain(1)

2012-07-17 09:13 by xiashengwang, 4293 阅读, 收藏, 编辑
摘要: 一,Appdomain概述 CLR COM服务器初始化时,会创建一个AppDomain。AppDomain是一组程序集的逻辑容器。宿主可以通过CLR创建额外的AppDomain。AppDomain的唯一作用就是隔离。下面是它的具体功能。●一个AppDomain中的代码创建的对象不能由另一个AppDomain中的代码直接访问。●AppDomain可以卸载。●AppDomain可以单独保护。AppDomain在创建后,会应用一个权限集,它决定了在这个AppDomain中运行的程序集的最大权限。●AppDomain可以单独实施配置。AppDomain在创建后,会关联一组配置设置。这些设置主要影响CL 阅读全文

《CLR via C#》笔记——程序集的加载和反射(3)

2012-07-16 17:54 by xiashengwang, 1492 阅读, 收藏, 编辑
摘要: 五,使用反射发现类型的成员1,发现类型成员 字段,构造器,方法,属性,事件和嵌套类都可以被定义为类型的成员。FCL定义了一个System.Reflection.MemberInfo的抽象基类,封装了一组所有类型成员都通用的属性。从MemberInfo派生的一组类,每个类都封装了与一个特定类型成员相关的属性。下面是这个类型的层次结构。下面的程序演示如何查询一个类型的成员并显示与它们相关的信息。以下代码中,处理AppDomain中加载的所有程序集中的公共类型,对每个类型,调用GetMembers方法,并返回由MemberInfo派生对象构成的一个数组;对每个成员都显示他们的种类(字段,构造器,方法 阅读全文

《CLR via C#》笔记——程序集的加载和反射(2)

2012-07-16 17:41 by xiashengwang, 680 阅读, 收藏, 编辑
摘要: 四,设计支持加载项的应用程序 构建可扩展应用程序时,接口是中心。可以利用基类来代替接口,但接口通常是首选,因为它允许加载项开发人员选择他们自己的基类。下面描述了如何构建这样的应用程序。1,创建一个“宿主SDK”(Host SDK)程序集。它定义一个接口,接口的方法作为宿主应用程序和加载项应用程序之间的通信机制使用。接口的参数和返回类型,尝试使用MSCorLib.dll中定义的类型或接口。如果要传递并返回自己定义的数据类型,也应该在这个“宿主SDK”程序集中定义。一旦搞定接口的定义,就可以为这个程序集赋一个强名称(版本控制),然后把它打包并部署到合作伙伴或用户那里。一旦发布就应避免对该程序集的做 阅读全文