2017-07-06 95 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休,我不知道这个类的,但它非常适合我的需要。 –