有什麼方法可以確定一個對象是否被鎖定在C#中?我有一個難以置信的地位,通過設計,我正在從一個班級裏的一個隊列裏讀書,我需要將這些內容轉儲到班級中的一個集合中。但是該集合也可以從類外部的接口讀取/寫入。所以顯然可能會出現集合正在寫入的情況,同時我想寫入該集合。有沒有辦法檢測對象是否被鎖定?
我可以對它進行編程,比如使用委託,但它會很難看。
有什麼方法可以確定一個對象是否被鎖定在C#中?我有一個難以置信的地位,通過設計,我正在從一個班級裏的一個隊列裏讀書,我需要將這些內容轉儲到班級中的一個集合中。但是該集合也可以從類外部的接口讀取/寫入。所以顯然可能會出現集合正在寫入的情況,同時我想寫入該集合。有沒有辦法檢測對象是否被鎖定?
我可以對它進行編程,比如使用委託,但它會很難看。
您可以始終使用Monitor
class上的靜態TryEnter
method呼叫等待值爲0。如果它被鎖定,則該呼叫將返回錯誤。
但是,這裏的問題是,您需要確保您嘗試同步訪問權限的列表被鎖定在自身上,以同步訪問權限。
通常不好的做法是使用正在同步訪問的對象作爲鎖定對象(暴露對象的內部細節太多)。
請記住,鎖可以在其他任何東西上,所以只要在列表中調用它就沒有意義,除非您確定該列表是被鎖定的。
Monitor.TryEnter
如果對象沒有被鎖定就會成功,如果此時對象被鎖定,將返回false。但是請注意,這裏存在隱式競爭:此方法返回的實例,對象可能不再被鎖定。
當前您可以調用Monitor.TryEnter來檢查對象是否被鎖定。
在.NET CLR 4.0團隊將添加 「鎖定檢查API」
這裏是Rick Byers文章報價:
鎖檢查
我們增加了一些簡單的API到ICorDebug,它允許您探索托管鎖(監視器)。例如,如果線程被阻塞等待鎖定,您可以找到其他線程當前正在鎖定的鎖定(以及是否有超時)。
所以,用這個API,你將能夠檢查:
1)什麼對象是持有鎖?
2)誰在等待?
希望這會有所幫助。
有趣。 鮑勃。 – 2009-08-19 15:03:30
我不知道如果一個靜態調用TryEnter的時間爲0將保證鎖定將不被獲取,如果它是可用的。我確實在調試模式下,測試溶液中的同步變量使用以下被鎖定:
#if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place. Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
if (acquired)
{
Monitor.Exit(SyncRoot);
}
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif
變量'isNotLocked'被命名得相當糟糕。如果'isNotLocked'爲真,則解鎖 - 雖然從技術上講它是正確的,因爲當鎖成功獲取時,isNotLocked將成立,上面的代碼真的不好閱讀。如果有其他人必須在此工作,他將有一個WTF時刻。 – ChrisWue 2013-10-20 20:12:01
如果運行的線程是擁有該鎖的線程,則不起作用。它會說鎖是免費的,但事實並非如此。 – 2014-09-19 17:34:42
確定當前線程是否在指定的對象上的鎖。
Available available 4.5
是的, 謝謝大家。這幾乎證實了我的想法。 – 2009-08-19 15:14:08