ReaderWriterLockSlim是否有与lock{}语句相当的等效语句?

9

我喜欢C#中lock(myLock){ /* do stuff */}的快捷方式。是否有读写锁的等效方法?(特别是ReaderWriterLockSlim)目前,我使用以下自定义方法,我认为它有效,但有点烦人,因为我必须将我的操作作为匿名函数传递,如果可能的话,我更愿意使用标准的锁定机制。

    void bool DoWithWriteLock(ReaderWriterLockSlim RWLock, int TimeOut, Action Fn)
    {
        bool holdingLock = false;
        try
        {
            if (RWLock.TryEnterWriteLock(TimeOut))
            {
                holdingLock = true;
                Fn();
            }
        }
        finally
        {
            if (holdingLock)
            {
                RWLock.ExitWriteLock();
            }
        }
        return holdingLock;
    }

1
try语句放错了位置。将它放在TryEnterWriteLock()之后。不再需要变量,快捷方式也变得无意义。 - Hans Passant
1个回答

14

无法覆盖lock关键字的行为。一种常见的技术是劫持using关键字。

  1. 使DoWithWriteLock返回一个IDisposable
  2. 保持TryEnterWriteLock调用在DoWithWriteLock方法内部
  3. 返回实现IDisposable的对象。在该对象的Dispose方法中,放置对ExitWriteLock的调用。

最终结果:

// Before
DoWithWriteLock(rwLock,
    delegate
    {
        Do1();
        Do2()
    } );

// After
using (DoWithWriteLock(rwLock))
{
    Do1();
    Do2();
}

1
在某些情况下,使用写锁可以更好:DoWithWriteLock(rwLock, () => { Do1(); Do2() } ); - Andrey
嗨,蒂姆。使用F#会更容易,这是真的吗? - jonnii
有没有类似的方式来实现 TryEnterWriteLock 带超时的锁定? - Xodarap
@jonnii F#的lock函数本质上就是OP原始的DoWithWriteLock,但使用了Monitor.Enterlock syncRoot (fun () -> do1 |> do2) - Tim Robinson
@Xodarap 如果你能找出一种方法,在返回 IDisposable 的同时,将 TryEnterWriteLock 的结果带出方法。也许可以这样:bool acquired; using (TryDoWithWriteLock(rwLock, out acquired)) {...} - Tim Robinson
2
在实际实现中,最好返回一个公开实现IDisposable的结构体(以避免不必要的堆分配和/或装箱);请参阅http://blogs.msdn.com/b/ericgu/archive/2004/03/24/95743.aspx 了解背景。 - Bradley Grainger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接