我正在尝试使用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表示它给出了等待进入的线程数,但是如何让线程等待进入呢?我在任何样本中都找不到。我是想循环直到它不抛出异常?这似乎不对。
答案 0 :(得分:2)
您在评论中说,您获得的例外是LockRecursionException
。
这意味着在某处:
线程正在点击EnterWriteLock
而该线程已经有写锁定,并且未使用LockRecursionPolicy.SupportsRecursion
创建锁定。不要用LockRecursionPolicy.SupportsRecursion
创建它;递归锁总是一个坏主意;确定你正试图获得已有锁的事实。 (更多关于为什么锁定递归不好的问题在https://stackoverflow.com/a/12014173/400547的答案中讨论)。
线程在具有读锁定时正在EnterWriteLock
。首先释放读锁定。
有一些包容性/排他性锁(AKA"读取器/写入器锁")允许代码在已经具有读锁定时获得写锁定。这虽然可以导致令人讨厌的死锁,如https://stackoverflow.com/a/8807232/400547的答案中所解释的那样,幸运的是ReaderWriterLockSlim
不支持这一点。首先释放读卡器锁,或使用可升级的锁。
或者实际上,由于涉及的工作涉及数据库,只需使用事务并让数据库处理并发问题。