ReaderWriterLockSlim如何等待进入锁定?

时间:2015-05-14 13:59:37

标签: c# multithreading asynchronous async-await

我正在尝试使用ReaderWriterLockSlim来锁定某些异步方法中的数据库工作,如下所示:

readerWriterLock.EnterWriteLock();
using (var db = new MyContextDB())
{
    // look something up and alter it
}
readerWriterLock.ExitWriteLock();

当多个线程同时尝试进入writelock时,会抛出异常。现在我可以使用一个锁定对象,但我想我会使用ReaderWriterLockSlim,所以我可以尝试使用read / write& amp;升级。

ReaderWriterLockSlim的MSDN示例对我来说有点混乱。是否有一种简单的方法让线程等待锁可用? IsWriteLockHeld属性表示它只测试当前线程是否被锁定。 WaitingWriteCount表示它给出了等待进入的线程数,但是如何让线程等待进入呢?我在任何样本中都找不到。我是想循环直到它不抛出异常?这似乎不对。

1 个答案:

答案 0 :(得分:2)

您在评论中说,您获得的例外是LockRecursionException

这意味着在某处:

  1. 线程正在点击EnterWriteLock该线程已经有写锁定,并且未使用LockRecursionPolicy.SupportsRecursion创建锁定。不要用LockRecursionPolicy.SupportsRecursion创建它;递归锁总是一个坏主意;确定你正试图获得已有锁的事实。 (更多关于为什么锁定递归不好的问题在https://stackoverflow.com/a/12014173/400547的答案中讨论)。

  2. 线程在具有读锁定时正在EnterWriteLock。首先释放读锁定。

  3. 有一些包容性/排他性锁(AKA"读取器/写入器锁")允许代码在已经具有读锁定时获得写锁定。这虽然可以导致令人讨厌的死锁,如https://stackoverflow.com/a/8807232/400547的答案中所解释的那样,幸运的是ReaderWriterLockSlim不支持这一点。首先释放读卡器锁,或使用可升级的锁。

    或者实际上,由于涉及的工作涉及数据库,只需使用事务并让数据库处理并发问题。