内部完全使用Monitor实现,理论上比使用WaitHandler的资源消耗更少,也更快。缺点是会损失一些功能。
Semaphore源码(btw:gotdotnet上面有一个ManagedThreadPool):
1using System;
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class SemaphoreLite
7 {
8 private int _count;
9 private object _sem = new object();
10
11 ctor.#region ctor.
12 public SemaphoreLite(int count)
13 {
14 _count = count;
15 }
16 #endregion
17
18 methods#region methods
19 public bool Wait()
20 {
21 return Wait(Timeout.Infinite);
22 }
23
24 public bool Wait(int millisecondsTimeout)
25 {
26 if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
27 {
28 throw new ArgumentOutOfRangeException("millisecondsTimeout 值应该大于0或等于Timeout.Infinite。");
29 }
30
31 lock (_sem)
32 {
33 if (_count <= 0)
34 {
35 if (!Monitor.Wait(_sem, millisecondsTimeout))
36 {
37 return false;
38 }
39 }
40 _count--;
41 return true;
42 }
43 }
44
45 public void WaitUntil(int amount)
46 {
47 lock (_sem)
48 {
49 while (_count < amount)
50 {
51 Monitor.Wait(_sem, Timeout.Infinite);
52 }
53 _count = _count - amount;
54 }
55
56 }
57
58 public void Pulse()
59 {
60 lock (_sem)
61 {
62 _count++;
63 Monitor.Pulse(_sem);
64 }
65 }
66 #endregion
67 }
68}
69
70
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class SemaphoreLite
7 {
8 private int _count;
9 private object _sem = new object();
10
11 ctor.#region ctor.
12 public SemaphoreLite(int count)
13 {
14 _count = count;
15 }
16 #endregion
17
18 methods#region methods
19 public bool Wait()
20 {
21 return Wait(Timeout.Infinite);
22 }
23
24 public bool Wait(int millisecondsTimeout)
25 {
26 if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
27 {
28 throw new ArgumentOutOfRangeException("millisecondsTimeout 值应该大于0或等于Timeout.Infinite。");
29 }
30
31 lock (_sem)
32 {
33 if (_count <= 0)
34 {
35 if (!Monitor.Wait(_sem, millisecondsTimeout))
36 {
37 return false;
38 }
39 }
40 _count--;
41 return true;
42 }
43 }
44
45 public void WaitUntil(int amount)
46 {
47 lock (_sem)
48 {
49 while (_count < amount)
50 {
51 Monitor.Wait(_sem, Timeout.Infinite);
52 }
53 _count = _count - amount;
54 }
55
56 }
57
58 public void Pulse()
59 {
60 lock (_sem)
61 {
62 _count++;
63 Monitor.Pulse(_sem);
64 }
65 }
66 #endregion
67 }
68}
69
70
AutoResetEvent源码:
1using System;
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class AutoResetEventLite
7 {
8 private object _sem = new object();
9 private bool _isSet;
10
11 private static int id = 0;
12 private int _currentId;
13
14 public methods#region public methods
15 public int ID
16 {
17 get { return _currentId; }
18 }
19
20 public AutoResetEventLite(bool initialState)
21 {
22 if (initialState)
23 {
24 _isSet = true;
25 }
26 else
27 {
28 _isSet = false;
29 }
30 Interlocked.Exchange(ref _currentId, id);
31 Interlocked.Increment(ref id);
32 }
33
34 public bool Wait()
35 {
36 return Wait(Timeout.Infinite);
37 }
38
39 public bool Wait(int millisecondsTimeout)
40 {
41 if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
42 {
43 throw new ArgumentOutOfRangeException("millisecondsTimeout 参数应该大于0或等于Timeout.Infinite。");
44 }
45
46 lock (_sem)
47 {
48 bool result;
49
50 if (!_isSet)
51 {
52 result = Monitor.Wait(_sem, millisecondsTimeout);
53 if (!result)
54
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class AutoResetEventLite
7 {
8 private object _sem = new object();
9 private bool _isSet;
10
11 private static int id = 0;
12 private int _currentId;
13
14 public methods#region public methods
15 public int ID
16 {
17 get { return _currentId; }
18 }
19
20 public AutoResetEventLite(bool initialState)
21 {
22 if (initialState)
23 {
24 _isSet = true;
25 }
26 else
27 {
28 _isSet = false;
29 }
30 Interlocked.Exchange(ref _currentId, id);
31 Interlocked.Increment(ref id);
32 }
33
34 public bool Wait()
35 {
36 return Wait(Timeout.Infinite);
37 }
38
39 public bool Wait(int millisecondsTimeout)
40 {
41 if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
42 {
43 throw new ArgumentOutOfRangeException("millisecondsTimeout 参数应该大于0或等于Timeout.Infinite。");
44 }
45
46 lock (_sem)
47 {
48 bool result;
49
50 if (!_isSet)
51 {
52 result = Monitor.Wait(_sem, millisecondsTimeout);
53 if (!result)
54