2017-07-06 93 views
-1

我遇到了(我希望)鎖死問題與WCF服務,我試着寫。線程和訪問共享目錄

我有一個功能,「定位」的下列鎖定特定項目即時通訊清單:通過這個列表

CIPRecipe FindRecipe_ByUniqueID(string uniqueID) 
    { 
     lock (_locks[LOCK_RECIPES]) 
     { 
      foreach (var r in _recipes.Keys) 
      { 
       if (_recipes[r].UniqueID == uniqueID) 
       { 
        return _recipes[r]; 
       } 
      } 
     } 
     return null; 
    } 

然而,各種功能重申,總是採用同樣的LOCK例如....

lock (_locks[LOCK_RECIPES_NO_ADD_OR_REMOVE]) 
      { 
       foreach (var r in _recipes) 
       { 
        r.Value.UpdateSummary(); 
        summaries.Add((RecipeSummary)r.Value.Summary); 
       } 
      } 

我懷疑是,在上面的例子中_recipes項目已突然叫一個函數,它最終調用的第一個功能 - 「CIPRecipe FindRecipe_ByUniqueID(字符串UNIQUEID)」,這是導致死鎖到達時在迭代中。

我需要停止這個名單不斷變化的,而我是通過迭代它。有人能告訴我最佳做法嗎?

感謝

+1

你應該看看到'ReaderWriterLockSlim' –

+0

謝謝,請升級到回答您的評論,我會接受它。 不知道爲什麼這個問題收到downvote雖然... –

回答

1

你想要的是穿過,但只有一個作家使用ReaderWriterLockSlim,這將讓無限的併發讀取和阻止,而作家是寫所有的讀者。

這是假設_locks已經從object[] chagned到ReaderWriterSlim[]

//On Read 
CIPRecipe FindRecipe_ByUniqueID(string uniqueID) 
{ 
    var lockObj = _locks[LOCK_RECIPES]; 
    lockObj.EnterReadLock(); 
    try 
    { 
     foreach (var r in _recipes.Keys) 
     { 
      if (_recipes[r].UniqueID == uniqueID) 
      { 
       return _recipes[r]; 
      } 
     } 
    } 
    finally 
    { 
     lockObj.ExitReadLock(); 
    } 
    return null; 
} 

//On write 
var lockObject = _locks[LOCK_RECIPES]; //Note this now uses the same lock object as the other method. 
lockObj.EnterWriteLock(); 
try 
{ 
    foreach (var r in _recipes) 
    { 
     r.Value.UpdateSummary(); 
     summaries.Add((RecipeSummary)r.Value.Summary); 
    } 
} 
finally 
{ 
    lockObj.ExitWriteLock(); 
} 

我不知道這是否會解決您的死鎖的問題,如果是你讓引起了寫它可以在讀取。

+0

感謝這個,這是更好的解決方案,只是用「鎖定(lockObject)」,雖然我用TryEnterWriteLock,TryEnterReadLock作爲一個額外的檢查。 –

1

也許ConcurrentDictionary叫這裏?

+0

Thanjs休,我不知道這個類的,但它非常適合我的需要。 –