0

All,

It seems really natural to me to use the IDisposable pattern to control a ReaderWriterLockSlim lock, since it allows locks to be cleaned up without the extra cruft of a try/catch block. I notice that there is nothing in the BCL to take care of this common(ish) task, so I wonder if my code below is really naive? I see some other questions on SO related to this general area, but nothing that tackles the appropriateness of this idea head-on.

The question also is not about whether the Dispose() method on ReaderWriterLockSlim object should be called, just the wrapper.

public class LockWrapper : IDisposable
{
    private readonly ReaderWriterLockSlim @lock;
    private readonly bool writeRequired;

    public LockWrapper(ReaderWriterLockSlim @lock, bool writeRequired)
    {
        this.@lock = @lock;
        this.writeRequired = writeRequired;

        if (writeRequired)
        {
            @lock.EnterWriteLock();
        }
        else
        {
            @lock.EnterReadLock();
        }
    }

    public void Dispose()
    {
        if (writeRequired && @lock.IsWriteLockHeld)
        {
            @lock.ExitWriteLock();
        }
        else if (@lock.IsReadLockHeld)
        {
            @lock.ExitReadLock();
        }
    }
}

Usage:

var @lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
using(var lockWrapper = new LockWrapper(@lock, true))
{
    //do something
}
Jon Bates
  • 3,055
  • 2
  • 30
  • 48
  • 1
    `using` based locks interact badly with thread abortion. But since you shouldn't abort them in the first place, it's not that bad. – CodesInChaos Nov 12 '12 at 13:25
  • @CodesInChaos Is that because the Dispose() method won't be called? – Jon Bates Nov 12 '12 at 16:46
  • 2
    Because there is a time window between the locking and the entering of the try-block where a thread abortion will not release the lock. – CodesInChaos Nov 12 '12 at 16:53
  • If you want to write these as an answer, i'd be happy to flag it as the answer. – Jon Bates Nov 23 '12 at 16:45
  • If I recall correctly, only some architectures have the issue. Still there is no warranty on the CLR part. You can mitigate the problem by adding a finalizer in your IDisposable wrapper to handle any leak... Still, don't abort your threads anyway. – Theraot Apr 05 '13 at 09:41
  • May I ask where you found that out? – Jon Bates Apr 06 '13 at 12:07
  • @JonBates https://blogs.msdn.microsoft.com/ericlippert/2009/03/06/locks-and-exceptions-do-not-mix/ – Niklas Peter Mar 19 '18 at 19:25

0 Answers0