使用LINQ锁定从字典中删除条目

时间:2010-03-06 10:00:35

标签: linq locking

我有一个静态字典,用于保存Web服务的身份验证。我正在运行一个计时器(因此在下面的方法上使用TimerCallBack sig)来删除那些已经休眠一段时间的身份验证。

我不太确定与linq相关的锁定行为。这是我的代码。我有点担心我可能会通过使用太多的锁来影响性能。例如如果只采用一个writelock并且没有读锁(即使没有认证已过期)会更好吗?

private static void RemoveExpiredAuthentications(object o)
{ 
    var expired = from a in _authentications
                  where a.Value.LastAccessed.AddSeconds(expired_interval_secs) < DateTime.Now 
                  select a;
    using (new ReadLock(dictionaryLock)) {
         expired.Select(e => {
             using (new WriteLock(dictionaryLock)){
                 _authentications.Remove(e.Value.Token);
             }
         }
     }
}

非常感谢

西蒙

2 个答案:

答案 0 :(得分:4)

我建议你想要删除首先的所有内容,然后在一个锁中完成所有操作:

var itemsToRemove = expired.Select(e => e.Value.Token).ToList();

using (new WriteLock(dictionaryLock))
{
    foreach (var removal in itemsToRemove)
    {
        _authentications.Remove(removal);
    }
}

除此之外,这意味着您在迭代时不会尝试从字典中删除项目。

(只是为了检查:每个条目的键是否与Token属性值相同?如果是,你可以使用e.Key而不是e.Value.Token - 这可能有点更加清晰。)

答案 1 :(得分:1)

foreach (var auth in expired) {
    using (new WriteLock(dictionaryLock)){
        _authentications.Remove(e => e.Value.Token);
    };
}

using (new WriteLock(dictionaryLock)){
    foreach (var auth in expired) {
        _authentications.Remove(e => e.Value.Token);
    };
}

如果您需要锁定,直到删除所有项目。

有时Linq不是最佳选择,但我不得不承认,很少。