本随笔续接:.NET 同步与异步 之 线程安全的集合 (十一)html
本随笔 及 接下来的两篇随笔,将介绍 .NET 同步与异步系列 的最后一个大块知识点:WaitHandle家族。编程
抽象基类:WaitHandle, 三个子类: EventWaitHandle(Event通知) 、Mutex(进程同步锁)、Semaphone (信号量),还有两个孙子辈:System.Threading.AutoResetEvent、System.Threading.ManualResetEvent,都是 EventWaitHandle 的子类。安全
[ComVisibleAttribute(true)] public abstract class WaitHandle : MarshalByRefObject, IDisposable
经过上面的信息,咱们能够知道 WaitHandle 继承自 MarshalByRefObject, 并实现了 IDisposable 接口。app
对于 MarshalByRefObject ,你也许不是很熟悉,但它的不少子类你必定会用过的,让咱们来揭开它的庐山真面目。异步
在MSND中是这样描述 MarshalByRefObject 的:ide
应用程序域是一个操做系统进程中一个或多个应用程序所驻留的分区。同一应用程序域中的对象直接通讯。不一样应用程序域中的对象的通讯方式有两种:一种是跨应用程序域边界传输对象副本,一种是使用代理交换消息。MarshalByRefObject 是经过使用代理交换消息来跨应用程序域边界进行通讯的对象的基类。函数
看到这里你也许更迷惑了,我用过它? 用过它的子类? 没错,就是用过它的子类,而且还不少。post
例如 System.Drawing命名空间的 Brush、Image、Pen、Font 等等,还有个你们更熟悉的 System.IO命名空间下的Stream.ui
延展阅读:利用 MarshalByRefObject 实现 AOP 。this
看到这里咱们只须要知道 WaitHandle 具备跨应用程序域进行通信的能力就能够了。
反观Monitor、平时只用来在应用程序域内的线程之间通讯。其实,若是用于锁的对象派生自MarshalByRefObject,Monitor 也可在多个应用程序域中提供锁定。
Mutex因为须要调用操做系统资源,所以执行的开销比Monitor大得多,因此若是仅仅须要在应用程序内部的线程间同步操做,Monitor/lock应当是首选
互斥体发出信号以指示不拥有。 在此状况下, WaitOne 方法将返回 true, ,调用线程的互斥体全部权,并访问由 mutex 保护的资源。 线程完成后访问资源,必须调用 ReleaseMutex 方法来释放 mutex 的全部权。
对调用中指定的超时间隔 WaitOne 具备方法 millisecondsTimeout 或 timeout 参数已过。 在此状况下, WaitOne 方法将返回 false, 此时该线程不会获取互斥体的全部权。
若是在一个应用程序域内使用Mutex,固然不如直接使用Monitor/lock更为合适,由于前面已经提到Mutex须要更大的开销而执行较慢。不过Mutex毕竟不是Monitor/lock,它生来应用的场景就应该是用于进程间同步的。用于在进程间通信的Mutex咱们称为全局Mutex,而只用于在应用程序域内部通信的Mutex、咱们称为局部Mutex.
全局Mutex和局部Mutex是经过构造函数来构造不一样的实例的,让咱们来看一下Mutex的构造函数,一共有5个,挑两个具备表明性的看一下吧:
Mutex天生为进程间的同步基元,所以它能够用来控制应用程序的单实例:
/// <summary> /// 单实例运行 /// </summary> /// <returns> true 应用程序已启动,false 则没有 </returns> public bool SingleRun(ref System.Threading.Mutex mutex ) { mutex = new System.Threading.Mutex(false, "WINDOWS"); if (!mutex.WaitOne(0, false)) { mutex.Close(); mutex = null; } if (mutex == null) { return true; } return false; }
未完待续,下一篇随笔: EventWaitHandle(Event通知)
附,Demo : http://files.cnblogs.com/files/08shiyan/ParallelDemo.zip
参见更多:随笔导读:同步与异步