多线程在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; } }