本隨筆續接:.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
參見更多:隨筆導讀:同步與異步