15

I have a situation whereby ReadWriterLockSlim is throwing the exception "System.Threading.SynchronizationLockException - The write lock is being released without being held." when I try to execute ExitWriteLock(). As far as I can tell, this shouldn't happen because subsequent threads that enter the try block will 'block' until they can obtain the lock. Am I missing something here?

The issue looks very similar to this one, however no solution was posted there.

//Code simplified for example. 

public class i18nService {
    internal static ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

    private string ProcessText()
    {
        try {
            cacheLock.EnterWriteLock();
            return "xyz";
        }
        finally {
            cacheLock.ExitWriteLock(); // Error is throwing here. 
        }
    }
}

Thanks very much for your help :-)

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
Damien Sawyer
  • 5,323
  • 3
  • 44
  • 56

2 Answers2

18

But if an error is thrown trying to enter the lock, then it will execute finally, without holding it. Why not simply change to:

...
finally {
    if(cacheLock.IsWriteLockHeld)
        cacheLock.ExitWriteLock();
}
...
Dan Gøran Lunde
  • 5,148
  • 3
  • 26
  • 24
Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
11
    try {
        cacheLock.EnterWriteLock();
        return "xyz";
    }
    finally {
        cacheLock.ExitWriteLock(); // Error is throwing here. 
    }

Q: What happens if cacheLock.EnterWriteLock(); fails?

A: The finally statement gets executed.

  • cacheLock.ExitWriteLock(); gets called
  • But we don't have the lock

Try this:

private string ProcessText()
{
    cacheLock.EnterWriteLock();
    try {
        return "xyz";
    }
    finally {
        cacheLock.ExitWriteLock(); // Error is throwing here. 
    }
}

Presumably .NET is designed in such a way that if EnterWriteLock() fails, the lock is released (or never held at all).

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • G'day Brendan. Thanks for the response. I actually thought along a similar line but am not sure that it's the case. from http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.enterwritelock.aspx "This method blocks until the calling thread enters the lock, and therefore might never return. Use the TryEnterWriteLock method to block for a specified interval, and then return if the calling thread has not entered write mode during that interval." However, as you point out, I am not allowing for an exception on EnterWriteLock()... hmmm... let me play with it some more. – Damien Sawyer Oct 12 '11 at 06:06
  • I always wondered in all the examples the write lock was before the try statement, but never an explanation given. Now it makes sense. – Chuck Savage Feb 06 '22 at 01:21