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
  • 51,248
  • 19
  • 139
  • 179
Damien Sawyer
  • 4,471
  • 3
  • 43
  • 52

2 Answers2

14

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
  • 4,368
  • 3
  • 23
  • 23
Petar Ivanov
  • 88,488
  • 10
  • 77
  • 93
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
  • 51,248
  • 19
  • 139
  • 179
  • 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