0

Albahari Threading section about ReaderWriterLockSlim shows usage of this locker. But there is no any try-catch and finally blocks against exceptional cases.

Why he hasn't used exception handling to not leave opened locks ? At below example, write lock left opened if DivideBy parameter is 0.

So he tries simply show usage for not to make example complicated? If so what is best practice to handle this problem ? We should to always use finally block for exit lock if it is held ?

public class Divide
{
    static int x = 1000;

    static ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

    public void DivideBy(int divide)
    {
        locker.EnterWriteLock();
        x = x / divide;
        locker.ExitWriteLock();
    }
}
apxcode
  • 7,696
  • 7
  • 30
  • 41
Freshblood
  • 6,285
  • 10
  • 59
  • 96
  • I would assume if an exception is thrown inside a lock, then as the error goes up the callstack, the lock is released – Jonesopolis Apr 26 '14 at 02:04
  • @Jonesy lets see which is right from incoming answers. I also wonder this. – Freshblood Apr 26 '14 at 02:06
  • why don't you just try it? – Jonesopolis Apr 26 '14 at 02:06
  • I am actually tested but threading is complex subject. My tests shows that it left opened but still i am not %100 sure about this at the moment. – Freshblood Apr 26 '14 at 02:08
  • take a look [here](http://stackoverflow.com/questions/590159/does-a-locked-object-stay-locked-if-an-exception-occurs-inside-it) – Jonesopolis Apr 26 '14 at 02:11
  • @Jonesy Lock keyword already release lock in finally block for you. But this is different than lock keyword. – – Freshblood Apr 26 '14 at 02:47
  • He did actually comment on this, perhaps you missed it? "In production code, you’d typically add try/finally blocks to ensure that locks were released if an exception was thrown." – J Trana Apr 26 '14 at 03:29
  • 1
    Why not follow the [MSDN example](http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx)...try/finally as previous comment mentions. – mdisibio Apr 26 '14 at 03:40
  • @mdisibio Right that is the answer. – Freshblood Apr 26 '14 at 03:43

2 Answers2

3

This is my personal pattern for dealing with this. I prefer to use using(IDisposable), as I find there is much less scope for errors with a single using block vs a try finally block.

public class Divide
{
    static int x = 1000;

    static ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

    public void DivideBy(int divide)
    {
        using(locker.DisposableWriteLock())
        {
            x = x / divide;     
        }
    }
}

public static class ReaderWriterLockSlimHelper
{
    public static IDisposable DisposableWriteLock(this ReaderWriterLockSlim readWriteLock)
    {
        readWriteLock.EnterWriteLock();
        return new LockContext(readWriteLock.ExitWriteLock);
    }

    private class LockContext : IDisposable
    {
        private Action _disposeContext;
        private bool _isDiposed;

        public LockContext(Action diposeContext)
        {
            _disposeContext = disposeContext;
        }

        public void Dispose()
        {
            if(_isDiposed)
                return;
            _disposeContext();
            _isDiposed = true;
        }
    }
}
Aron
  • 15,464
  • 3
  • 31
  • 64
  • Nice i also thought similar approach. Do you use this code in production ? Do you also write extension method for ReadLock ? – Freshblood Apr 26 '14 at 04:09
  • Not with ReaderWriterLock, and I typically use the Rx Disposable helpers. – Aron Apr 26 '14 at 04:11
  • Same solution from another question http://stackoverflow.com/questions/170028/how-would-you-simplfy-entering-and-exiting-a-readerwriterlock – Freshblood Apr 26 '14 at 05:12
2

The typical idiom is to use try...finally:

public void DivideBy(int divide)
{
    locker.EnterWriteLock();
    try
    {
        x = x / divide;
    }
    finally
    {
        locker.ExitWriteLock();
    }
}

That will ensure that the lock is released in case of exception. However, pay heed to Eric Lippert's Locks and exceptions do not mix. You should try to make your lock body (i.e. whatever you do while you hold the lock) is as short and simple as possible so as to reduce the chance of throwing exceptions.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351