是否有任何情况下,在ReaderWriterLockSlim上调用EnterWriteLock应该输入读锁定?

MKi*_*ing 5 .net c# parallel-processing asynchronous locking

我有一个看似非常简单的情况,我在.NET Framework的3.5版本中使用System.Threading.ReaderWriterLockSlim.我首先声明一个,如下所示:

锁定声明http://odeh.temp.s3.amazonaws.com/lock_declaration.bmp

我在获得锁定之前设置了一个断点并拍摄了一个屏幕截图,以便您可以看到(在监视窗口中)当前没有锁定:

预锁获取http://odeh.temp.s3.amazonaws.com/prelock.bmp

然后,在调用EnterWriteLock后,您可以看到我正在按住Read Lock.

锁定后收购http://odeh.temp.s3.amazonaws.com/postlock.bmp

这似乎是真正意想不到的行为,我无法在任何地方找到它.有没有人知道为什么会这样?在我的代码中的其他地方(前面),这个完全相同的代码行正确地获得了写锁定.然而,在多个系统中,它始终在调用堆栈中的这个位置获得读锁定.希望我已经明确表示,并感谢您抽出时间来研究这个问题.

---编辑---

那些提到断言的人......这让我更加困惑:

断言http://odeh.temp.s3.amazonaws.com/assert.bmp

我真的不能说它是如何通过这个断言,除了可能Watch Window和Immediate窗口是错误的(也许值是本地存储线程,如另一张海报所提到的).对于一个易变量和一个Happens Before关系来说,这似乎是一个明显的例子.无论哪种方式,之后的几行都有代码,这些代码为写锁定而没有一个.我已经在整个程序中的唯一一行代码中设置了一个断点,它释放了这个锁,并且在这里显示的获取之后它没有被调用,所以这必然意味着它从未实际获得过......对吗?

Han*_*ant 3

这可能是调试器的副作用。ReaderWriterLockSlim 类对当前线程 ID (Thread.ManagedThreadId) 非常敏感。我无法声明调试器将始终使用当前活动线程来计算监视表达式。通常是这样,但可能会出现不同的行为,例如,如果您通过硬中断进入调试器。

首先相信代码的作用,您的 Debug.Assert 证明了这一点。