C#有ThreadPool和Task,为什么还要自己写线程池?我以前也没想过自己写线程池,都是用ThreadPool或Task,前段时间写爬虫,我想控制10个线程爬网页、10个线程下载网页上的图片,不然的话因为网页很多,图片相对较少,可能大部分线程都在爬网页,少量线程在下载图片,这样下载图片的速度慢了,所以我想到了自己写线程池MyThreadPool,再配合ThreadPool使用,精确控制爬网页和下载图片的线程数。不过这个线程池写的比较简单,缺点是线程池会瞬间创建最大数量的工作线程。
线程池类代码:
using System; System.Collections.Concurrent; System.Collections.Generic; System.Linq; System.Text; System.Threading; namespace Utils { /// <summary> /// 线程池 </summary> public static class MyThreadPool { <summary> 最大工作线程数 </summary> private int m_WorkerThreads = 5; 线程队列 static ConcurrentQueue<MyThread> m_ThreadQueue = new ConcurrentQueue<MyThread>(); 任务队列 static ConcurrentQueue<Tuple<Action<object>,object>> m_Action = new ConcurrentQueue<Tuple<Action<object>>(); 创建并启动线程 </summary> <param name="action"></param> <param name="obj"></param> void Start(Action<object> action,1)">object obj = null) { m_Action.Enqueue(new Tuple<Action<object>(action,obj)); MyThread thread; if (m_ThreadQueue.Count < m_WorkerThreads) { thread = new MyThread(); m_ThreadQueue.Enqueue(thread); thread.isWorker = true; //设置为工作线程 thread.thread = new Thread(new ThreadStart(() => { Tuple<Action< tuple; while (thread.isWorker) 如果是工作线程,则一直循环 { if (m_Action.TryDequeue(out tuple)) 如果任务队列中有任务,则取出任务执行 { tuple.Item1(tuple.Item2); 执行任务 } else { Thread.Sleep(100); } Thread.Sleep(1); } })); thread.thread.IsBackground = true; thread.thread.Start(); } } 设置最大工作线程数 <param name="workerThreads">最大工作线程数</param> void SetMaxThreads(int workerThreads) { m_WorkerThreads = workerThreads; MyThread thread = ; while (m_ThreadQueue.Count > m_WorkerThreads) { m_ThreadQueue.TryDequeue(out thread); thread.isWorker = false; Thread.Sleep(); } } 获取最大工作线程数 GetMaxThreads() { return m_WorkerThreads; } 获取当前工作线程数 GetWorkerThreads() { m_ThreadQueue.Count; } } 线程 MyThread { 线程 public Thread thread { get; set; } 是否工作线程 bool isWorker { ; } } }
测试代码:
System.ComponentModel; System.Data; System.Drawing; System.IO; System.Threading; System.Threading.Tasks; System.Windows.Forms; Common.Utils; System.Collections.Concurrent; test { partial Form1 : Form { int errorCount = 0; int errorCount2 = object _lock = new object(); int dataCount = 30 任务执行总次数 int runcount = ; public Form1() { InitializeComponent(); } void Form1_Load( sender,EventArgs e) { ThreadPool.SetMaxThreads(20,20); StringBuilder sb = StringBuilder(); for (int k = 1; k <= dataCount; k++) { sb.AppendFormat("{0},",k.ToString(00")); } lblMsg2.Text = sb.ToString(); timer1.Tick += new EventHandler((obj,ea) => { int maxThreads = MyThreadPool.GetMaxThreads(); int workerThreads = MyThreadPool.GetWorkerThreads(); lblMsg.Text = string.Format({0}/{1}(工作线程数/最大工作线程数),workerThreads,maxThreads); ThreadPool.GetMaxThreads(out workerThreads,out maxThreads); lblMsg.Text = string.Format("{0}/{1}(最大辅助线程数/最大I/O线程数)",maxThreads); if (workerThreads > maxThreads) { errorCount++; lblError.Text = 错误(工作线程数超过最大工作线程数)次数:" + errorCount.ToString() + ,错误(线程内代码执行结果错误)次数:" + errorCount2.ToString(); } if (lblMsg2.Text != sb.ToString()) { errorCount2++ errorCount2.ToString(); LogUtil.LogError(lblMsg2.Text); } lblruncount.Text = 任务执行总次数: runcount.ToString(); }); timer1.Interval = ; timer1.Start(); lblError.Text = 暂没有错误; } 开始 void button1_Click(); ThreadPool.SetMaxThreads(); button1.Enabled = ; Thread thread = while () { List<int> list = new List<int>(); int i = 1; i <= dataCount; i++) { ThreadPool.QueueUserWorkItem((obj) => Task.Factory.StartNew((obj) => MyThreadPool.Start((obj) => { int n = ()obj; lock (_lock) { list.Add(n); } if (list.Count == dataCount) { list.sort(); StringBuilder sb = StringBuilder(); 0; k < list.Count; k++) { sb.AppendFormat()); } this.Invoke(new MyInvoke(() => { lblMsg2.Text = sb.ToString(); })); runcount++; } },i); } Thread.Sleep(); } })); thread.IsBackground = ; thread.Start(); } 设置最大工作线程数 void button2_Click( d; if (int.TryParse(txtMaxThreads.Text,1)"> d)) { if (d > ) { MyThreadPool.SetMaxThreads(d); ThreadPool.SetMaxThreads(d,d); } { txtMaxThreads.Text = 1; } } { txtMaxThreads.Text = 20; } } } delegate void MyInvoke(); }
测试截图:
@H_36_502@
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。