微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

自已写的线程池

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 { ; }
    }
}
View Code

测试代码

 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();
}
View Code

测试截图:

@H_36_502@

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐