« 上一篇

C#实现顺序执行的Thread工具类

一. 实现的方法

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. 测试结果

测试结果截图如下: