开发者

Remove entries from dictionary using LINQ - locking

开发者 https://www.devze.com 2022-12-21 22:42 出处:网络
I have a static dictionary which holds authentications for a web service. I\'m running a timer (hence the TimerCallBack sig on the method below) to remove those authentications which have been dormant

I have a static dictionary which holds authentications for a web service. I'm running a timer (hence the TimerCallBack sig on the method below) to remove those authentications which have been dormant for a period.

I'm not quite sure of the locking behaviour I need in relation to linq. Here's my code thus. I'm slightly concerned that I may affect performance by using too many locks. e.g. Would it be better to just take a single writelock and no readlocks (even if no authentications had expired)?

private static void RemoveExpiredAuthentications(object o)
{ 
    var expired = from a in _authentications
                  whe开发者_开发技巧re 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);
             }
         }
     }
}

Many thanks

Simon


I would suggest working out everything you want to remove first, and then doing it all in one lock:

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

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

Aside from anything else, this means you won't be trying to remove an item from the dictionary while iterating over it.

(Just to check: is the key to each entry the same as the Token property value? If so, you can just use e.Key rather than e.Value.Token - that may be somewhat clearer.)


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

or

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

if you ndeed to lock until all items are removed.

Sometimes Linq is not the best choice, although, I have to admit, rarely.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号