线程和访问共享列表

时间:2017-07-06 16:08:05

标签: c# multithreading wcf

我遇到(我希望)我正在尝试写的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)”,这在迭代中到达时会导致死锁。

我需要在我迭代它时停止更改这个列表。有人可以告诉我最佳做法吗?

由于

2 个答案:

答案 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();
}

我不知道它是否会解决您的死锁问题,如果它是由您在写入期间允许读取引起的。