现在的位置: 首页 > 综合 > 正文

更轻量级的Semaphore、AutoResetEvent、ThreadPool

2013年12月10日 ⁄ 综合 ⁄ 共 3111字 ⁄ 字号 评论关闭
内部完全使用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        #region ctor.
12        public SemaphoreLite(int count)
13        {
14            _count = count;
15        }

16        #endregion

17
18        #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        #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

抱歉!评论已关闭.