线程池

来源:互联网 发布:ubuntu pppoe拨号 编辑:程序博客网 时间:2024/05/13 22:51

“线程池”是可以用来在后台执行多个任务的线程集合。这使主线程可以自由地异步执行其他任务。

线程池通常用于服务器应用程序。每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会占用主线程,也不会延迟后续请求的处理。

一旦池中的某个线程完成任务,它将返回到等待线程队列中,等待被再次使用。这种重用使应用程序可以避免为每个任务创建新线程的开销。

线程池通常具有最大线程数限制。如果所有线程都繁忙,则额外的任务将放入队列中,直到有线程可用时才能够得到处理。

您可以实现自己的线程池,但是通过 ThreadPool 类使用 .NET Framework 提供的线程池更容易一些。

下面的示例使用 .NET Framework 线程池实现单线程下载和多个线程下载的效果:

前台界面如下:

后台代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;

namespace WindowsForm多线程复习
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ThreadStart start = new ThreadStart(DownLoad);
            Thread thread = new Thread(start);
            thread.Start();
        }

        private void Mianji(object r)
        {
            double result = Math.PI * Convert.ToInt32(r) * Convert.ToInt32(r);
            this.Invoke(new Action(delegate()
            {
                MessageBox.Show(result.ToString());
            }));
        }
        private void DownLoad()
        {
            for (int i = 30000; i < 30010; i++)
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        client.DownloadFile(@"http://job.cnblogs.com/offer/" + i + "/", @"G:\movices\" + i + ".html");
                        //使用匿名委托的简写方式
                        this.Invoke(new Action(delegate()
                        {
                            this.textBox1.AppendText("第" + i + "个帖子已经下载完成\n");

                        }));
                    }
                }
                catch (Exception ex) { }
           
            }
            Action action = new Action(Msg);
            this.Invoke(action);
       
        }
        private void Msg()
        { MessageBox.Show("下载完成"); }
       
        private void button2_Click(object sender, EventArgs e)
        {
            ParameterizedThreadStart start = new ParameterizedThreadStart(Mianji);
            Thread thread = new Thread(start);
            thread.Start(5);
        }
        //使用线程池下载帖子
        private void button3_Click(object sender, EventArgs e)
        {
            //这么写其实只是让线程池启动了一个线程,没有利用多线程来操作
            WaitCallback wait = new WaitCallback(DownLoadThreadPool);
            ThreadPool.QueueUserWorkItem(wait);

        }
        private void DownLoadThreadPool(object obj)
        {
            for (int i = 30000; i < 30010; i++)
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        client.DownloadFile(@"http://job.cnblogs.com/offer/" + i + "/", @"g:\movices\" + i + ".html");
                        //使用匿名委托的简写方式
                        this.Invoke(new Action(delegate()
                        {
                            this.textBox1.AppendText("第" + i + "个帖子已经下载完成\n");
                        }));
                    }
                }
                catch (Exception ex) { }
            }
            Action action = new Action(Msg);
            this.Invoke(action);
       
        }
        //线程池多现场下载
        private void button4_Click(object sender, EventArgs e)
        {
            for (int i = 30000; i < 30020; i++)
            {
                WaitCallback wait = new WaitCallback(DownLoadThreadPool2);
                ThreadPool.QueueUserWorkItem(wait, i);
            }
        }
        private void DownLoadThreadPool2(object obj)
        {
            try
            {
                using (WebClient client = new WebClient())
                {
                    client.DownloadFile(@"http://job.cnblogs.com/offer/" + Convert.ToInt32(obj) + "/", @"g:\movices\" + Convert.ToInt32(obj) + ".html");
                    //使用匿名委托的简写方式
                    this.Invoke(new Action(delegate()
                    {
                        this.textBox1.AppendText("第" + Convert.ToInt32(obj) + "个帖子已经下载完成\n");
                    }));
                }
            }
            catch (Exception ex) { }
        }
    }
}

分别实现一下两种效果:

从以上可以看出使用线程池,并不是先放进去的方法先执行,而是线程池根据实际情况自己来决定先执行哪个方法。还有就是并不是向线程池放进几个委托,线程池就开启几个线程去执行,而是根据cpu以及内存的使用情况,自己决定开启几个线程,也许你放进去10个委托,而线程池只开启了3个线程来执行