2016-06-16 52 views
0

我想知道一個調用Monitor.TryEnter的故障安全方法。 文檔顯示它是這樣的:如何調用Monitor.TryEnter

if (Monitor.TryEnter(lockObj)) { 
    try { 
     // The critical section. 
    } 
    finally { 
     // Ensure that the lock is released. 
     Monitor.Exit(lockObj); 
    } 
} 

由於這是「官方」的方式來稱呼它,我毫不猶豫地做任何事情。但我不覺得很舒服代碼: 假設我們得到這樣一個ThreadAbortException:

if (Monitor.TryEnter(lockObj)) { 
    // *** ThreadAbortException happens exactly here 
    try { 
     [...] 
    } 
    finally { [...] } 
} 

這是否不會離開我是永遠不會釋放鎖?

+0

爲什麼不使用'lock(lockObj){...}'而不是?此外,ThreadAbortException通常不是問題,因爲無論如何,流程/ appdomain都將被拆除。 –

+0

@Lasse:當鎖已被佔用時,鎖將不允許我做別的事情。 threadAbortException不僅在進程被拆除時發生,還有更多的方法來終止線程。 –

回答

2

你說得對。因此推薦使用Monitor.TryEnter的方式是:

bool lockAcquired; 

try 
{ 
    Monitor.TryEnter(lockObj, ref lockAcquired); 

    if (lockAcquired) 
    { 
     DoSomething(); 
    } 
} 
finally 
{ 
    if (lockAcquired) 
    { 
     Monitor.Exit(lockObj); 
    } 
} 
+0

謝謝!我認爲TryEnter(lock)的代碼是建議的代碼,但現在我發現那是不太優選的重載的首選代碼。 –

0

它可以。你可以用finally試塊封閉所有Monitor(帶有布爾超載)。

關於你的ThreadAbortException的例子,這是一個特殊的例子。 如果在卸載應用程序域後CLR拋出,CLR會照顧你做它需要的東西,並且在此應用程序域中將不會運行任何代碼,因此你不必擔心。

如果你手動把它,以任何方式,你將在一個糟糕的狀態...

至於側面說明看一看here,關於編碼器在鎖定的情況下釋放的信任的例外。