1 internal sealed class RecursiveAutoResetEvent : IDisposable
2 {
3 private AutoResetEvent m_lock = new AutoResetEvent(true);
4
5 //拥有锁的线程ID
6 private int m_owningThredId = 0;
7
8 //递归锁计数
9 private int m_recursiveCount = 0;
10
11 public void Enter()
12 {
13 //获取调用线程的唯一Int32 ID
14 int currentThreadId = Thread.CurrentThread.ManagedThreadId;
15
16 //如果调用线程拥有锁就递增递归计数
17 if (Equals(m_owningThredId, currentThreadId))
18 {
19 //代码走到这里说明是同一个线程需要获得锁,只需将递归计数加1
20 m_recursiveCount++;
21 return;
22 }
23
24 //代码走到这里说明另一个线程需要获得锁
25 //调用线程未拥有锁就等待
26 m_lock.WaitOne();
27
28 //调用线程现在拥有了锁,初始化拥有线程的ID和递归计数
29 m_owningThredId = currentThreadId;
30 m_recursiveCount = 1;
31 }
32
33 public void Leave()
34 {
35 //如果调用线程不拥有锁就出错
36 if (!Equals(m_owningThredId, Thread.CurrentThread.ManagedThreadId))
37 {
38 throw new InvalidOperationException();
39 }
40
41 //从递归计数减1(表示释放一次递归锁)
42 m_recursiveCount--;
43 //如果递归计数为0,表明该线程不再拥有锁(递归锁),或者说是递归中的最后一个锁已被释放
44 if (Equals(m_recursiveCount, 0))
45 {
46 //初始化并且唤醒一个正在等待的线程(如果有)
47 m_owningThredId = 0;
48 m_lock.Set();
49 }
50 }
51
52 public void Dispose()
53 {
54 m_lock.Dispose();
55 }
56 }