分享一个秒计数器
在实际应用中我们经常要对一个或多个操作进行一个简单的秒操作数量计算,由于在.net里找不到这样一个类,所以实现了这样一个功能类并分享出来.这个类的主要功能是可以记录一个或多个的秒讲数处理,并每秒触发一个通知事件提供每一项的讲数情况包括:当前秒数量,最大数和平均值等.
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace Smark 6 { 7 /// <summary> 8 /// Copyright © henryfan 2012 9 /// Email: henryfan@msn.com 10 /// HomePage: http://www.ikende.com 11 /// CreateTime: 2012/10/27 21:56:05 12 /// </summary> 13 public class SecondCounter : IDisposable 14 { 15 public SecondCounter() 16 { 17 mTimer = new System.Threading.Timer(OnCallBack, this, 10, 990); 18 } 19 20 private System.Diagnostics.Stopwatch mStopwatch = new System.Diagnostics.Stopwatch(); 21 22 /// <summary> 23 /// 计数描述接口 24 /// </summary> 25 interface ICounter 26 { 27 /// <summary> 28 /// 执行 29 /// </summary> 30 void Process(); 31 /// <summary> 32 /// 重置信息 33 /// </summary> 34 void Reset(); 35 } 36 /// <summary> 37 /// 计数项 38 /// </summary> 39 public class CounterItem : ICounter 40 { 41 private long mCount = 0; 42 private long mLastCount; 43 private int mTickCount; 44 public int Max 45 { 46 get; 47 private set; 48 49 } 50 public int Avg 51 { 52 get; 53 private set; 54 } 55 public int Min 56 { 57 get; 58 private set; 59 } 60 61 public int Value 62 { 63 get; 64 private set; 65 } 66 public string Name 67 { 68 get; 69 set; 70 } 71 public void Add() 72 { 73 System.Threading.Interlocked.Increment(ref mCount); 74 } 75 public long Count 76 { 77 get 78 { 79 return mCount; 80 } 81 } 82 public void Add(long value) 83 { 84 System.Threading.Interlocked.Add(ref mCount, value); 85 } 86 void ICounter.Process() 87 { 88 mTickCount++; 89 Value = (int)(mCount - mLastCount); 90 mLastCount = mCount; 91 if (Value < Min) 92 Min = Value; 93 if (Value > Max) 94 Max = Value; 95 Avg = (int)(Count / mTickCount); 96 } 97 public override string ToString() 98 { 99 return string.Format("{0}:\t{1}/s[Count:{2},Max:{3},Avg:{4}]", Name, Value, mCount, Max, Avg); 100 101 102 } 103 104 105 void ICounter.Reset() 106 { 107 mTickCount = 0; 108 mCount = 0; 109 Value = 0; 110 mLastCount = 0; 111 Max = 0; 112 Min = 99999; 113 } 114 } 115 /// <summary> 116 /// 回调事件 117 /// </summary> 118 public event Action<IList<CounterItem>> Tick; 119 private List<CounterItem> mItems = new List<CounterItem>(); 120 /// <summary> 121 /// 添加计数项 122 /// </summary> 123 /// <param name="name">计数项名称</param> 124 /// <returns>CounterItem</returns> 125 public CounterItem Add(string name) 126 { 127 CounterItem item = new CounterItem(); 128 item.Name = name; 129 mItems.Add(item); 130 return item; 131 } 132 133 private bool mIsPause = true; 134 135 /// <summary> 136 /// 开始计数 137 /// </summary> 138 public void Start() 139 { 140 141 mIsPause = false; 142 for (int i = 0; i < mItems.Count; i++) 143 { 144 ((ICounter)mItems[i]).Reset(); 145 } 146 mStopwatch.Reset(); 147 mStopwatch.Start(); 148 149 } 150 151 public double UseTimes 152 { 153 get 154 { 155 return mStopwatch.Elapsed.TotalMilliseconds; 156 } 157 } 158 159 /// <summary> 160 /// 暂停计数 161 /// </summary> 162 public void Pause() 163 { 164 mIsPause = true; 165 mStopwatch.Stop(); 166 } 167 168 private void OnCallBack(object state) 169 { 170 if (!mIsPause) 171 { 172 for (int i = 0; i < mItems.Count; i++) 173 { 174 ((ICounter)mItems[i]).Process(); 175 } 176 try 177 { 178 if (Tick != null) 179 { 180 Tick(mItems); 181 } 182 } 183 catch 184 { 185 } 186 } 187 } 188 189 private System.Threading.Timer mTimer; 190 191 private bool mIsDisposed = false; 192 193 public void Dispose() 194 { 195 lock (this) 196 { 197 if (!mIsDisposed) 198 { 199 if (mTimer != null) 200 mTimer.Dispose(); 201 mIsDisposed = true; 202 } 203 } 204 } 205 } 206 }
使用
计数器的使用也很简单,定义具体的项;在指定的地方添加计数即可:
1 static SecondCounter mSCounter; 2 static SecondCounter.CounterItem ci1; 3 static SecondCounter.CounterItem ci2; 4 static SecondCounter.CounterItem ci3; 5 static Random mRan = new Random(); 6 static void Main(string[] args) 7 { 8 mSCounter = new SecondCounter(); 9 ci1 = mSCounter.Add("TEST1"); 10 ci2 = mSCounter.Add("TEST2"); 11 ci3 = mSCounter.Add("TEST3"); 12 mSCounter.Tick += (s) => { 13 foreach (SecondCounter.CounterItem item in s) 14 { 15 Console.WriteLine(item); 16 } 17 }; 18 19 System.Threading.ThreadPool.QueueUserWorkItem(Test1); 20 System.Threading.ThreadPool.QueueUserWorkItem(Test2); 21 System.Threading.ThreadPool.QueueUserWorkItem(Test3); 22 mSCounter.Start(); 23 Console.Read(); 24 25 } 26 27 static void Test1(object state) 28 { 29 while (true) 30 { 31 ci1.Add(); 32 System.Threading.Thread.Sleep(mRan.Next() % 100); 33 } 34 } 35 static void Test2(object state) 36 { 37 while (true) 38 { 39 ci2.Add(); 40 System.Threading.Thread.Sleep(mRan.Next() % 100); 41 } 42 } 43 static void Test3(object state) 44 { 45 while (true) 46 { 47 ci3.Add(); 48 System.Threading.Thread.Sleep(mRan.Next() % 100); 49 } 50 } 51
使用情况图
访问Beetlex的Github