2012-02-10 81 views
3

如果我有以下代碼:C#鎖定恢復/繼續/打破

lock(SyncRoot){ return value; } 

將SyncRoot上被return語句之前解鎖?

我嘗試瞭解VS2005中的代碼,但實際上並沒有表現出這種或那種方式。它看起來像解開它,但我想確保。

回答

3

是的,無論您如何退出該塊(即返回,休息,拋出等),它都會解鎖。

詳情請參閱MSDN - lock statement

lock關鍵字可確保在另一個線程處於臨界區一個線程不會進入代碼的臨界段。
...
lock關鍵字調用在塊的開始處輸入並在 結束處退出。

2

是的,它計算值(如果值是一個表達式,這可能很重要),然後解鎖並返回。無論您如何操作,鎖定()始終會在您退出其範圍時自動解鎖。

1

它將在塊執行後解鎖。

此語法類似於using,順便說一句。 lock在塊之外的唯一原因是要顯示在啓動時有一個鎖,在結束時解鎖功能。

0

不,鎖只釋放返回聲明。

3

是的,你可以把它擴展到像這樣的:

Monitor.Enter(obj); 
try { 
    var result = value; 
} 
finally { 
    Monitor.Exit(obj); 
} 
return result; 

如果你看一下生成的IL,它是類似的東西。如果value是一個表達式,它將在釋放鎖之前進行評估。釋放鎖後執行返回。

在任何情況下都會調用finally塊,所以是的,鎖被釋放。

2

請記住,lock實際上在後臺使用了Monitor.Enter/Monitor.Exit。你的代碼的擴展版本,其實這

Monitor.Enter (SyncRoot); 
try 
{ 
    return value; 
} 
finally { Monitor.Exit (SyncRoot); } 

finally塊是保證方法實際上返回之前執行,所以鎖被釋放。

1

如果你有類似` int i = 0; object o = new object();

 while (i < 100) 
     { 
      lock (o) 
      { 
       if (i == 10) 
        continue; 
      } 

      ++i; 
     }` 

這將導致死鎖,因爲 它會永遠等待獲取 鎖從以前的執行 背景下保存繼續