0

关于 ReaderWriterLockSlim的Albahari Threading部分显示了此储物柜的用法。但是没有任何 try-catch 和 finally 阻止例外情况。

为什么他没有使用异常处理来不留下打开的锁?在下面的示例中,如果 DivideBy 参数为 0,则写锁保持打开状态。

所以他试图简单地展示用法而不是让例子变得复杂?如果是这样,处理这个问题的最佳做法是什么?如果它被持有,我们应该总是使用 finally 块作为退出锁吗?

public class Divide
{
    static int x = 1000;

    static ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

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

2 回答 2

3

这是我处理此问题的个人模式。我更喜欢使用using(IDisposable),因为我发现单个 using 块与 try finally 块相比,错误的范围要小得多。

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;
        }
    }
}
于 2014-04-26T03:51:40.300 回答
2

典型的习惯用法是使用 try...finally:

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

这将确保在发生异常时释放锁。但是,请注意 Eric Lippert 的Locks 和 exceptions do not mix。您应该尽量使您的锁体(即您在持有锁时所做的任何事情)尽可能短而简单,以减少抛出异常的机会。

于 2014-04-26T03:49:23.620 回答