C#之多线程

      多线程在C#中使用得非常频繁,线程之间的充分利用显得尤为重要,一般的写法都是得不到充分利用资源,本人针对多线程写了一种方法,可以充分利用资源,保证每次同时启动10条线程,现在执行完马上再启动一条,总之线程维持10条。

1. 线程启动方法,使用while死循环,获取需要计算的参数和创建线程。

   while (true)
            {
                bool isALlSuccess = IsALlSuccess(fundCodes);//判断全部数据有没有执行完
                if (isALlSuccess)//所有风控全部走完后则跳出while循环
                {
                    //Log.Log.Debug("个券指令相关性判断完成!");
                    break;
                }
                if (ThrowFlag)//多线程执行失败
                {
                    break;
                }
                //--
                string fundcode = GetFund(fundCodes);//获取单个基金
                if (fundcode == null) continue;
                //--
                Thread t = GetThread();//获取线程
                if (t == null) continue;
                AutoResetEvent are = new AutoResetEvent(false);
                InternalThreadInfo tti = new InternalThreadInfo(are, fundcode);
                //t.Name = "Thread" + irisk.ToString();
                t.Start(tti);//启动线程

                //已执行的基金
                SetInsIndex();
            }

动态创建多线,保存每次都会执行10条线程。

      #region * 获取线程
        private List<Thread> Ts = new List<Thread>();//定义线程的集合
        private Thread GetThread()
        {
            Thread td = null;
            if (Ts.Count < 10)
            {
                td = new Thread(TheeadMod);
                Ts.Add(td);
            }
            else
            {
                for (int i = 0; i < Ts.Count; i++)
                {
                    if (Ts[i] == null)
                    {
                        Ts[i] = new Thread(TheeadMod);
                        td = Ts[i];
                        break;
                    }
                }
            }
            return td;
        }
        #endregion

用于判断多线主要计算的行、数组是否计算完毕。

    #region * 判断多线程是否已经执行完毕
        private int successCount = 0;//运行成功的行数
        /// <summary>
        /// 判断多线程是否已经执行完毕
        /// </summary>
        /// <returns></returns>
        private Boolean IsALlSuccess(List<string> fundcodes)
        {
            if (successCount >= fundcodes.Count)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

获取一条数据,用户传递到多线程里。

     #region * 获取一条单个基金
        private int InsIndex = 0;
        /// <summary>
        /// 获取一条风控条目
        /// </summary>
        /// <returns></returns>
        private string GetFund(List<string> fundcodes)
        {
            if (InsIndex < fundcodes.Count)
            {
                string str = fundcodes[InsIndex];
                return str;
            }
            else
            {
                return null;
            }
        }
        #endregion

主要用于计数。

    #region * 自增已执行的基金
        /// <summary>
        /// 自增已执行的风控条目
        /// </summary>
        private void SetInsIndex()
        {
            //lock (insIndexLockObject)
            //{
            InsIndex++;
            //}
        }
        #endregion

        #region * 自增线程已执行成功
        /// <summary>
        /// 自增线程已执行成功
        /// </summary>
        private void SetSuccessIndex()
        {
            //lock (successLockObject)
            //{
            successCount++;
            //}
        }
        #endregion

多线程执行的主要方法,线程执行完后,都会Set掉,并将数据的对于的线程清空。

  #region * 多线程执行的方法
        private void TheeadMod(object fundcodes)
        {
            try
            {
                InternalThreadInfo tti = fundcodes as InternalThreadInfo;
                string fundCode = tti.obj as string;
                   
//--执行的核心代码 //--............................
SetSuccessIndex();
//调用计数器 #region * 线程的控制 for (int i = 0; i < Ts.Count; i++) { Thread t = Ts[i]; if (t != null && t.Name == Thread.CurrentThread.Name) { Ts[i] = null; break; //t.Join(); } } tti.are.Set(); #endregion } catch (Exception ex) { ThrowFlag = true; Log.Error("多线程执行出错:" + ex.Message); //ErrorMsg = ex.Message; } } #endregion

类:InternalThreadInfo用于给多线程传统参数,are主要是多线程执行的状态,obj主要是传递的参数,可以是实体类、string、datarow行。

    internal class InternalThreadInfo
    {
        public AutoResetEvent are = null;
        public object obj = null;
        public InternalThreadInfo(AutoResetEvent are, object obj)
        {
            this.are = are;
            this.obj = obj;
        }
    }
原文地址:https://www.cnblogs.com/jara/p/3724385.html