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

测试结果截图如下:

 

 

posted @ 2019-11-20 10:13  霁雪湖上三映月  阅读(665)  评论(0)    收藏  举报