tags:

views:

212

answers:

2

Hi

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
                  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);
             }
         }
     }
}

Many thanks

Simon

A: 
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.

Obalix
Wow ... very quick. Many thx. Could you explain why please? Thx again
Simon Woods
+1  A: 

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.)

Jon Skeet
Wrt Token ... yes you are correct. Many thx
Simon Woods