Search code examples
c#.netmultithreadingreaderwriterlockslim

Is it completely safe to use pattern of ReaderWriterLockSlim.EnterXXX() with consequent try-finally clause


MSDN Documentation and many examples of using ReaderWriterLockSlim class recommends using the following pattern:

cacheLock.EnterWriteLock();
try
{
    //Do something
}
finally
{
    cacheLock.ExitWriteLock();
}

But I'm curious if it's completely safe. Is it possible that some exception will happen after lock is acquired, but before the try statement so that lock is stuck in the locked state? The most obvious candidate is ThreadAbortException. I understand that probability of this situation is extreemely small, but the consequences are extreemely bad - so I think it worth thinking about it. I don't believe compiler understands this pattern and prevents processor from interrupting thread before try statement.

If there is theoretical possibility that this code is unsafe, and is there ways to make it safer?


Solution

  • It can be an issue and apparently is in some high-load scenarios. This article goes into it further, but it basically boils down to using an empty try block coupled with a finally to acquire & release the lock:

    var lockIsHeld = false;
    try {
       try {
       }
       finally {
          rwl.EnterReadLock();
          lockIsHeld = true;
       }
    
       // Do work here
    }
    finally {
       if (lockIsHeld) {
          rwl.ExitReadLock();
       }
    }
    

    This approach guarantees that your lock is always acquired and release as finally blocks are guaranteed to run even in the case of a ThreadAbortException.

    Other exceptions are detailed in @hvd's post.

    Personally I wouldn't worry about it unless you actually see this issue in the wild...