C# 自定义固定数量线程池
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace A9AgentApp.Task { public class CustomThread { #region Variable //一个AutoResetEvent实例 private AutoResetEvent _locks = new AutoResetEvent(false); //一个Thread实例 private Thread _thread; // 绑定回调方法,就是外部实际执行的任务 public WaitCallback _taskAction; //定义一个事件用来绑定工作完成后的操作 public event Action<CustomThread> WorkCompleted; /// <summary> ///设置线程拥有的Key /// </summary> public string Key { get; set; } /// <summary> /// 当前线程消息输出Action /// </summary> public Action<String> MessageWriterAction; #endregion //线程需要做的工作 private void Work() { while (true) { //判断信号状态,如果有set那么 _locks.WaitOne()后的程序就继续执行 _locks.WaitOne(); // 将当前线程实例传到Action里 _taskAction(this); // Console.WriteLine("Thread:" + Thread.CurrentThread.ManagedThreadId + "workComplete"); //执行完成事件 WorkCompleted(this); } } #region event //构造函数 public CustomThread() { // 初始化线程 _thread = new Thread(Work); _thread.IsBackground = true; Key = Guid.NewGuid().ToString(); //线程开始执行 _thread.Start(); Console.WriteLine("Thread:" + _thread.ManagedThreadId + " has been created!"); } //Set开起信号 public void Active() { _locks.Set(); } #endregion } public class CustomFixedThreadPool { #region Variable //创建的线程数 private int TreadCount = 6; //空闲线程队列 private Queue<CustomThread> _freeThreadQueue; //工作线程字典(为什么?) private Dictionary<string, CustomThread> _workingDictionary; //空闲队列,存放需要被执行的外部函数 private Queue<WaitCallback> _waitTaskQueue; #endregion #region Event /// <summary> /// 自定义线程池的构造函数 /// </summary> /// <param name="MessageWriteActions">线程输出消息方法列表</param> public CustomFixedThreadPool(List<Action<String>> MessageWriteActions) { _workingDictionary = new Dictionary<string, CustomThread>(); _freeThreadQueue = new Queue<CustomThread>(); _waitTaskQueue = new Queue<WaitCallback>(); CustomThread task = null; //产生固定数目的线程 for (int i = 0; i < TreadCount; i++) { task = new CustomThread(); //给每一个任务绑定事件 if (MessageWriteActions.Any()) { task.MessageWriterAction = MessageWriteActions[i % MessageWriteActions.Count]; } else { task.MessageWriterAction = (msg) => { }; } task.WorkCompleted += new Action<CustomThread>(WorkComplete); //将每一个新创建的线程放入空闲队列中 _freeThreadQueue.Enqueue(task); } } //线程任务完成之后的工作 void WorkComplete(CustomThread obj) { lock (this) { //将线程从字典中排除 _workingDictionary.Remove(obj.Key); //将该线程放入空闲队列 _freeThreadQueue.Enqueue(obj); //判断是否等待队列中有任务未完成 if (_waitTaskQueue.Count > 0) { //取出一个任务 WaitCallback item = _waitTaskQueue.Dequeue(); CustomThread newTask = null; //空闲队列中取出一个线程 newTask = _freeThreadQueue.Dequeue(); // 线程执行任务 newTask._taskAction = item; //把线程放入到工作队列当中 _workingDictionary.Add(newTask.Key, newTask); //设置信号量 newTask.Active(); return; } else { return; } } } //添加任务到线程池 public void AddTaskItem(WaitCallback taskItem) { lock (this) { CustomThread task = null; //判断空闲队列是否存在线程 if (_freeThreadQueue.Count > 0) { //存在线程,取出一个线程 task = _freeThreadQueue.Dequeue(); //将该线程放入工作队列 _workingDictionary.Add(task.Key, task); //执行传入的任务 task._taskAction = taskItem; //设置信号量 task.Active(); return; } else { //空闲队列中没有空闲线程,就把任务放到等待队列中 _waitTaskQueue.Enqueue(taskItem); return; } } } #endregion } }
2.使用方法 (初始化线程池)
infoLabels = new List<Label>() { this.lbl_info1, this.lbl_info2, this.lbl_info3, this.lbl_info4, this.lbl_info5, this.lbl_info6 }; List<Action<String>> infoLabelWriters = new List<Action<string>>(); foreach(Label label in infoLabels) { infoLabelWriters.Add((msg) => label.CrossThreadRun(()=>label.Text = msg)); } customThreadPool = new CustomFixedThreadPool(infoLabelWriters);
3. 使用方法(完成任务)
for(int i = 0; i < 10; i++) { customThreadPool.AddTaskItem((t) => { var msgWriter = ((CustomThread)t).MessageWriterAction; for(int j = 0; j < 1000; j++) { msgWriter("正在执行第"+(1+j).ToString()+"/1000 条"); Thread.Sleep(10); } msgWriter("执行完成!"); }); }
或 (增加任务完成标识)
((Button)sender).Enabled = false; int flag = 0; for (int i = 0; i < 10; i++) { customThreadPool.AddTaskItem((t) => { Interlocked.Increment(ref flag); var msgWriter = ((CustomThread)t).MessageWriterAction; for(int j = 0; j < 1000; j++) { msgWriter("正在执行第"+(1+j).ToString()+"/1000 条"); Thread.Sleep(10); } msgWriter("执行完成!"); Interlocked.Decrement(ref flag); if (flag == 0) { ControlUtil.CrossThreadRun((Button)sender, () => ((Button)sender).Enabled = true); } }); }
4. 辅助类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace A9AgentApp.utils { public static class ControlUtil { /// <summary> /// 跨线程访问控件 在控件上执行委托 /// </summary> /// <param name="ctl">控件</param> /// <param name="del">执行的委托</param> public static void CrossThreadRun(this Control ctl, ThreadStart process) { if (process == null) return; if (ctl.InvokeRequired) { ctl.Invoke(process, null); } else { process(); } } /// <summary> /// 跨线程访问控件 在控件上执行委托 /// </summary> /// <param name="ctl">控件</param> /// <param name="del">执行的委托</param> public static Object CrossThreadCall (this Control ctl, Func<Object> func) { if (ctl.InvokeRequired) {return ctl.Invoke(func, null); } else { return func(); } } } }