Self-written thread pool, self-written Thread Pool

Source: Internet
Author: User

Self-written thread pool, self-written Thread Pool

C # I have ThreadPool and Task. Why do I need to write the thread pool? I have never thought about writing a thread pool myself before. I used ThreadPool or Task to write crawlers some time ago. I want to control 10 threads crawling webpages and 10 threads downloading images on webpages, otherwise, because there are many webpages and there are relatively few images, most of the threads may be crawling the webpage, and a small number of threads are downloading images, which slows down the download speed, so I thought of my own write thread pool MyThreadPool, and then used with ThreadPool to precisely control the number of threads crawling webpages and downloading images. However, this thread pool is relatively simple to write, but the disadvantage is that the thread pool will instantly create the maximum number of working threads.

 

Thread Pool code:

Using System; using System. collections. concurrent; using System. collections. generic; using System. linq; using System. text; using System. threading; namespace Common. utils {// <summary> /// thread pool /// </summary> public static class MyThreadPool {/// <summary> /// maximum number of working threads // /</summary> private static int m_WorkerThreads = 10; /// <summary> /// thread queue /// </summary> private static ConcurrentQueue <MyThread> m_ThreadQueue = new ConcurrentQueue <MyThread> (); /// <summary> // task queue // </summary> private static ConcurrentQueue <Tuple <MyAction, object> m_Action = new ConcurrentQueue <Tuple <MyAction, object >>> (); /// <summary> /// create and start a thread // </summary> /// <param name = "action"> </param> /// <param name = "obj"> </param> public static void Start (MyAction action, object obj = null) {m_Action.Enqueue (new Tuple <MyAction, object> (action, obj); MyThread thread; if (m_ThreadQueue.Count <m_WorkerThreads) {thread = new MyThread (); m_ThreadQueue.Enqueue (thread); thread. isWorker = true; // set it to the worker thread. thread = new Thread (new ThreadStart () => {Tuple <MyAction, object> tuple; while (thread. isWorker) // if it is a working thread, it will keep repeating {if (m_Action.TryDequeue (out tuple) // if there is a task in the task queue, it will take out the task and execute {tuple. item1 (tuple. item2); // execution task} Thread. sleep (1) ;}}); thread. thread. isBackground = true; thread. thread. start ();}} /// <summary> /// set the maximum number of worker threads /// </summary> /// <param name = "workerThreads"> maximum number of worker threads </param> public static void SetMaxThreads (int workerThreads) {m_WorkerThreads = workerThreads; MyThread thread = null; while (m_ThreadQueue.Count> m_WorkerThreads) {m_ThreadQueue.TryDequeue (out thread); thread. isWorker = false; Thread. sleep (1) ;}/// <summary> /// obtain the maximum number of working threads /// </summary> public static int GetMaxThreads () {return m_WorkerThreads ;} /// <summary> /// obtain the current number of worker threads /// </summary> public static int GetWorkerThreads () {return m_ThreadQueue.Count ;}} /// <summary> /// task /// </summary> /// <param name = "obj"> task parameter </param> public delegate void MyAction (object obj ); /// <summary> /// Thread // </summary> public class MyThread {// <summary> // Thread // </summary> public Thread thread {get; set ;}//< summary> /// whether the worker thread is running /// </summary> public bool isWorker {get; set ;}}}View Code

Test code:

Using System; using System. collections. generic; using System. componentModel; using System. data; using System. drawing; using System. IO; using System. linq; using System. text; using System. threading; using System. threading. tasks; using System. windows. forms; using Common. utils; using System. collections. concurrent; namespace test {public partial class Form1: Form {private static int errorCount = 0; private static Int errorCount2 = 0; private static object _ lock = new object (); private static int dataCount = 30; /// <summary> /// total number of task executions /// </summary> private static int runCount = 0; public Form1 () {InitializeComponent ();} private void Form1_Load (object sender, EventArgs e) {ThreadPool. setMaxThreads (20, 20); StringBuilder sb = new 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} (number of worker threads/Maximum number of worker threads)", workerThreads, maxThreads); // ThreadPool. getMaxThreads (out workerThreads, out maxThreads); // lblMsg. text = string. format ("{0}/{1} (maximum number of auxiliary threads/maximum I /O thread count) ", workerThreads, maxThreads); if (workerThreads> maxThreads) {errorCount ++; lblError. text = "error (the number of worker threads exceeds the maximum number of worker threads):" + errorCount. toString () + ", error (in-thread code execution result error) times:" + errorCount2.ToString ();} if (lblMsg2.Text! = Sb. toString () {errorCount2 ++; lblError. text = "error (the number of worker threads exceeds the maximum number of worker threads):" + errorCount. toString () + ", error (in-thread code execution result error) times:" + errorCount2.ToString (); LogUtil. logError (lblMsg2.Text);} lblRunCount. text = "Total number of task executions:" + runCount. toString () ;}); timer1.Interval = 100; timer1.Start (); lblError. text = "no error";} // start private void button#click (object sender, EventArgs e) {MyThreadPool. setMaxThreads (20); ThreadPool. setMaxThreads (20, 20); button1.Enabled = false; Thread thread = new Thread (new ThreadStart () => {while (true) {List <int> list = new List <int> (); for (int I = 1; I <= dataCount; I ++) {// ThreadPool. queueUserWorkItem (obj) => // Task. factory. startNew (obj) => MyThreadPool. start (obj) => {int n = (int) obj; lock (_ lock) {list. add (n);} if (list. count = dataCount) {list. sort (); StringBuilder sb = new StringBuilder (); for (int k = 0; k <list. count; k ++) {sb. appendFormat ("{0},", list [k]. toString ("00");} this. invoke (new MyInvoke () => {lblMsg2.Text = sb. toString () ;})); runCount ++ ;}, I) ;} Thread. sleep (1) ;}}); thread. isBackground = true; thread. start () ;}// set the maximum number of worker threads private void button2_Click (object sender, EventArgs e) {int d; if (int. tryParse (txtMaxThreads. text, out d) {if (d> 0) {MyThreadPool. setMaxThreads (d); ThreadPool. setMaxThreads (d, d);} else {txtMaxThreads. text = "1" ;}} else {txtMaxThreads. text = "20" ;}} public delegate void MyInvoke ();}View Code

Test:

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.