同步處理(LockContext),期待大家的意見

2022-01-22 15:34:05 字數 2645 閱讀 4652

背景

關於它的名字

解決的問題

設計分析

**展示

設計缺陷

最近由於要處理很多同步的問題,所以寫了不少這方面的**。最為顯著的有已經在blog上提到的object cache。還有接下來要向大家展示的lockcontext。

首先,lockcontext這個名稱是否合適還值得商榷,因為這裡面使用了lock,但其解決的問題當某乙個物件還未完成初始化時,所有被其處理的事件通知都要等待。關於名稱,我沒有多想,因為我的目的是為了解決當前的問題。所以,當你讀完**時,有了新的想法,歡迎你與我分享。

當控制項的例項被建立後,控制項開始了資料的初始化任務,由於控制項需要載入的資料量大,由於網路等因素,使資料的載入時間長,因而使得控制項的初始化過程耗時較長。

而在另外一方面,當控制項的例項化完成後,控制項已經能夠事件通知(在我的具體環境下,事件通知是由伺服器發出的)。

因此,問題就出來了:在控制項初始化的過程中,處理事件通知,會導致怪異的錯誤。

有人可能要問,找到到底是什麼樣的事件通知導致了錯誤,這是可以分析的。但我這裡的環境是,控制項載入的資料量和資料種類多,與此同時,來至於伺服器端的事件通知也多,就算是分析清楚了錯誤,將這個具體的錯誤解決,也不能保證這樣的錯誤會在今後的維護工作中繼續發生。

因此,就需要通過某種機制解決這個問題,即當控制項處於初始化狀態時,當前檢視訪問該控制項的其它執行緒都會被掛起。當控制項初始化完成後再執行這些掛起的任務。

該類用於保證初始化執行緒被鎖定。如果initjob沒有被建立或者沒有被解鎖,那麼其它runjob將不能加鎖。當其中乙個runjob加鎖後,其餘的runjob只能等待。

initjob與runjob等待鎖的時間是有限的,如果在等待的時間內沒有加鎖成功那麼job例項的failed將會返回true。這也使得使用該機制的**能夠體面的處理加鎖失敗問題。

你可以直接返回,如下面**

using(var state = mlockcontext.initjob(null))

你也可以丟擲異常來改變程式的流程,如以下**

uisng(var state = mlockcontext.run(null))

正如上面的**展示,我選擇了using塊的方式來體面地使用job。這樣將加鎖和解鎖過程體面地影藏起來。

using(var state = mlockcontext.run(null))

正如「解決的問題」塊中提到的,要使用這樣的**,就得將其放在類的初始化方法、其它public方法和事件通知處理方法中,保證該類的入口都有mlockcontext「把守」。

例如:

class acontrol : control

}public

void methoda()

}public

void methodb()

}}

using system;

using system.collections.generic;

using system.text;

using system.diagnostics;

using system.threading;

namespace opencourse.openactivity.windows.views

public lockcontext()

public

class initjob : idisposable

public initjob(bool state)

public initjob(lockcontext context)

: this(true)

#region idisposable members

public

void dispose()

}#endregion

}public initjob init(string jobdescription)

else

}public

class runjob : idisposable

private lockcontext mcontext;

public runjob(bool state)

public runjob(lockcontext context)

: this(true)

#region idisposable members

public

void dispose()

#endregion

}public runjob run(string jobdescription)

if (!string.isnullorempty(jobdescription))

trace.writeline(jobdescription + " tries to enter the lock");

if (monitor.tryenter(mlockobj, mlocktimeinseconds * 1000))

else

}public

void resetstate()

}}

從上面的例子**可以發現, mlockcontext都是被用於public方法。但是,如果method a 呼叫了method b,那後果是method b不能成功執行,因為鎖已經被method a占用了。

執行緒同步處理

假如你在行駛的高鐵上想上廁所,於是你走到廁所門前,發現提示燈提示裡面有人,那麼你只能等待。如果多個人想上廁所,那麼就要排隊。這個時候廁所只能在同一時刻給乙個人使用。同樣的道理,在多執行緒中處理同步問題時引入同步鎖的概念,同步鎖類似於廁所的門,它將單獨的個體關在廁所裡,其他人想進也進不去。同步鎖的關鍵...

spring jms同步訊息處理

spring框架中直接封裝了jms的處理。在處理jms訊息時會更加方便。spring處理同步訊息時採用的jmstemplate的方法。配置檔案如下,封裝activemq的方法 同步接收的 如下,因為需要對接收到的訊息進行處理,所以重寫的jmstemplate的execute方法 序列化成string...

介面和內部處理同步

最近用到乙個程式,對資源占用比較多,這樣介面就死掉了。因此另外開乙個執行緒去做操作,但是介面執行緒要知道子執行緒什麼時候結束。研究了一下csdn,採用autoresetevent類解決。首先宣告乙個全域性的 private autoresetevent ar 在介面執行緒中 ar new autor...