我有一个静态字典,用于保存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);
}
}
}
}
非常感谢
西蒙
答案 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不是最佳选择,但我不得不承认,很少。