Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error with ReaderWriterLockSlim

I got this exception
The read lock is being released without being held.
at System.Threading.ReaderWriterLockSlim.ExitReadLock() at .. GetBreed(String)

Below is the only place in code that accesses the lock. As you can see, there is no recursion. I'm having trouble understanding how this exception could occur.

static readonly Dictionary<string, BreedOfDog> Breeds 
     = new Dictionary<string,BreedOfDog>();

static BreedOfDog GetBreed(string name)
{
        try
        {
            rwLock.EnterReadLock();
            BreedOfDog bd;
            if (Breeds.TryGetValue(name, out bd))
            {
                return bd;
            }
        }
        finally
        {
            rwLock.ExitReadLock();
        }

        try
        {
            rwLock.EnterWriteLock();
            BreedOfDog bd;
            //make sure it hasn't been added in the interim
            if (Breeds.TryGetValue(t, out bd)
            {
                return bd;
            }
            bd = new BreedOfDog(name); //expensive to fetch all the data needed to run  the constructor, hence the caching

            Breeds[name] = bd;
            return bd;
        }
        finally
        {
            rwLock.ExitWriteLock();
        }
}  
like image 341
dan Avatar asked Apr 24 '12 17:04

dan


1 Answers

I'm guessing you have something re-entrant, and it is throwing an exception when obtaining the lock. There is a catch-22 whether you "take the lock", "try" vs "try", "take the lock", but the "take the lock", "try" has fewer failure cases (the "aborted between take and try" is so vanishingly unlikely you don't need to stress).

Move the "take the lock" outside the "try", and see what the actual exception is.

The problem is most likely that you are failing to take the lock (probably re-entrancy), then trying to unlock something you didn't take. This could mean that the exception surfaces in the orginal code that took the lock, due to trying to release twice when only taken once.

Note: Monitor has new overloads with "ref bool" parameters to help with this scenario - but not the other lock types.

like image 81
Marc Gravell Avatar answered Oct 11 '22 15:10

Marc Gravell