C# 自定义固定数量线程池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | 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(); } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2020-11-17 使用Integer存储版本号
2017-11-17 java获取缓存通用类
2016-11-17 通用缓存类