我遇到(我希望)我正在尝试写的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(string uniqueID)”,这在迭代中到达时会导致死锁。
我需要在我迭代它时停止更改这个列表。有人可以告诉我最佳做法吗?
由于
答案 0 :(得分:1)
也许在这里调用ConcurrentDictionary?
答案 1 :(得分:1)
你想要的是使用ReaderWriterLockSlim
,这将允许无限制的并发读者通过,但只有一个作者通过并阻止所有读者在作者写作时。
这假设_locks
已从object[]
转为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();
}
我不知道它是否会解决您的死锁问题,如果它是由您在写入期间允许读取引起的。