一. 实现的方法
1. 使用并发集合 ConcurrentDictionary,主要是这个并发集合是一个线程安全的集合;
2. 使用 Monitor 来保证一直只有一个线程处理任务的就绪队列;
二. 实现工具类代码
OrderedThread 是按照顺序执行的线程类,代码如下:
/// <summary>/// 顺序线程 线程按执行顺序/// </summary>public class OrderedThread { #region 静态字段 /// <summary> /// 当前的线程循序序号 /// </summary> private static int _inner_orderedID = 0; /// <summary> /// 当前的线程的队列 /// </summary> private static ConcurrentDictionary<int, OrderedThread> inner_readyThreadList = new ConcurrentDictionary<int, OrderedThread>(); /// <summary> /// 线程锁 /// </summary> private static object _objLock = new object(); #endregion #region 成员字段 /// <summary> /// 处理的委托 /// </summary> private Action<int> _inner_action = null; #endregion #region 构造函数 /// <summary> /// 构造函数 /// </summary> /// <param name="handling">处理的委托</param> public OrderedThread(Action<int> handling) { this._inner_action = handling; } #endregion #region 开始执行线程 /// <summary> /// 开始执行线程 /// </summary> public void Start() { //添加到就绪集合中 inner_readyThreadList.AddOrUpdate(_inner_orderedID++, this, (key, vlaue) => { return this; }); Thread th = new Thread(() => { bool isEnter = Monitor.TryEnter(_objLock); if (isEnter) { //如果就绪队列中有要执行的线程 while (inner_readyThreadList.Count() > 0) { //找到起始的最小值 int minIndex = inner_readyThreadList.Keys.Min(); //绪队列中线程执行 inner_readyThreadList[minIndex]._inner_action.Invoke(minIndex); //移除执行完成的 OrderedThread orderedThreadTmp = null; inner_readyThreadList.TryRemove(minIndex, out orderedThreadTmp); } Monitor.Exit(_objLock); } }); th.SetApartmentState(ApartmentState.STA); th.IsBackground = true; th.Start(); } #endregion}
3. 测试代码
相关的测试代码如下:
static void Main() { for (int i = 0; i < 20; i++) { if (i == 10) { Thread.Sleep(10000); } OrderedThread orderedThread = new OrderedThread((o) => { Console.WriteLine("第一轮:当前的线程序号" + o); Thread.Sleep(1000); Console.WriteLine(DateTime.Now.ToString()); }); orderedThread.Start(); } Console.WriteLine("第一轮全部开始了..."); for (int i = 0; i < 20; i++) { OrderedThread orderedThread = new OrderedThread((o) => { Console.WriteLine("第二轮:当前的线程序号" + o); Thread.Sleep(1000); Console.WriteLine(DateTime.Now.ToString()); }); orderedThread.Start(); } Console.WriteLine("第二轮全部开始了..."); Console.ReadKey(); }
4. 测试结果
测试结果截图如下: