由於最近使用Parallel for的平行化迴圈來運算
debug了一陣子都找不出問題所在
最後才知道遇上了critical section的問題
搜尋了一下C#提供了三種方法
Monitor,Mutex,和Semaphor
(可參閱此網誌的介紹)
其中最常見的方法就是Monitor的方法
而最簡易的方式就是使用lock指令
(lock就是實作Monitor的方法)
msdn lock方法
但lock卻有許多能力上的限制
看似簡單卻有許多小陷阱
可參考此網誌
介紹的蠻詳細的
在目前處理影像的部分由於Multi-Threading(多執行緒)跟非同步的關係
需要對同一個物件(影像)做存取
最簡單,又不會有問題的方式
就是自行宣告一個private 的物件作為lock的instance,如下:
(最好還是唯讀)
private Readonly Object _ThisLock = new Object(); private Bitmap _Frame; ... lock (this._ThisLock) { //存取 _Frame 的 Critical code section. } ...
如果有外部程式需要存取到此影像物件_Frame的話
就必須提供此物件的public的屬性讓外部程式參考使用
(通常不應該由外部程式來控制互斥鎖,應該在內部做掉)
public Bitmap Frame { get { Bitmap bmp=null; lock(this._ThisLock) { bmp=this._Frame.clone() as Bitmap; } return bmp; } }
這樣就可以達到外部程式取得此物件時的安全性
但是內部程式每次在控制_Frame的時候都要寫一次lock實在很麻煩
所以可以將Frame加入set的功能
public Bitmap Frame { get { Bitmap bmp=null; lock(this._ThisLock) { bmp=this._Frame.clone() as Bitmap; } return bmp; } private set { lock(this._ThisLock) { if(this._Frame!=null) this._Frame.Dispose(); this._Frame=value; } } }由於_Frame只可由內部做設定
所以使用private set的方式來處理
避免外部程式來設定_Frame
這樣以後內部程式在做_Frame存取時就直接使用Frame
既可達到封裝效果(其實只是偷懶...),又完成thread save的存取
當然這只是簡單的存取機制
如果需要對_Frame做比較複雜的存取
就還是要自己寫了互斥鎖了!!
沒有留言:
張貼留言