.NET ThreadPool 线程池 控制台 和 Winform 应用
一.控制台程序应用线程池
namespace ThreadPoolExample { class Program { static void Main() { WaitCallback callBack = new WaitCallback(PooledFunc); ThreadPool.QueueUserWorkItem(callBack, "ABC"); ThreadPool.QueueUserWorkItem(callBack, "BCD"); ThreadPool.QueueUserWorkItem(callBack, "CDE"); Console.ReadLine(); } static void PooledFunc(object state) { int ThisThreadNumber=Thread.CurrentThread.GetHashCode(); bool isThreadPoolThread=Thread.CurrentThread.IsThreadPoolThread; Console.WriteLine(string.Format("线程{0} 已开始,是否为线程池中的线程: {1}",ThisThreadNumber,isThreadPoolThread.ToString())); //暂停4秒 Thread.Sleep(4000); Console.WriteLine(string.Format("线程{0} 已结束,是否为线程池中的线程: {1}", ThisThreadNumber, isThreadPoolThread.ToString())); } } }
运行结果如图所示:(我们可以清楚的看到线程池先后启动了3个线程来执行相应方法)
=====================================================================================================
二.Winform 应用程序使用ThreadPool
1.窗体类 Form1.cs
public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// 点击开始按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { //自定义执行类 ExeCuteManager execute = new ExeCuteManager(); execute.StateChangeEvent += new ExeCuteManager.DelArgInfo(execute_StateChangeEvent);//执行状态更改,事件订阅 WaitCallback callBack = new WaitCallback(execute.DelPolFun); ThreadPool.QueueUserWorkItem(callBack, 1); ThreadPool.QueueUserWorkItem(callBack, 2); ThreadPool.QueueUserWorkItem(callBack, 3); } void execute_StateChangeEvent(string strTipInfo, int Number,bool IsEnd) { if (this.InvokeRequired) { this.BeginInvoke(new ExeCuteManager.DelArgInfo(DelPolfun), new object[] { strTipInfo, Number, IsEnd }); } else { DelPolfun(strTipInfo, Number, IsEnd); } } /// <summary> /// 将状态信息添加到 ListBox控件(listBox1) /// </summary> /// <param name="strTipInfo"></param> /// <param name="Number"></param> /// <param name="IsEnd"></param> private void DelPolfun(string strTipInfo, int Number,bool IsEnd) { this.listBox1.Items.Add(strTipInfo); if (Number == 3 && IsEnd) { this.listBox1.Items.Add(string.Format("所有的线程执行结束!")); } } }
2.自定义执行类ExeCuteManager.cs
/// <summary> /// 执行类 /// </summary> public class ExeCuteManager { /// <summary> /// 执行状态改变通知界面显示--委托 /// </summary> /// <param name="strTipInfo"></param> /// <param name="Number"></param> /// <param name="IsEnd"></param> public delegate void DelArgInfo(string strTipInfo,int Number,bool IsEnd); /// <summary> /// 执行状态更改--事件 /// </summary> public event DelArgInfo StateChangeEvent; public void DelPolFun(object _stateInfo) { int IntNumber=(int)_stateInfo; //获得当前线程的哈希码(标识线程在线程池中的唯一) int ThisThreadNumber=Thread.CurrentThread.GetHashCode(); //指示当前线程是否属于托管线程池 bool isThreadPool=Thread.CurrentThread.IsThreadPoolThread; if (StateChangeEvent != null) { string strTip = string.Format("请求 {0} 开始,线程哈希码为{1},是否为线程池线程:{2},...", IntNumber, ThisThreadNumber, isThreadPool.ToString()); StateChangeEvent(strTip, IntNumber,false); } Thread.Sleep(4000); if (StateChangeEvent != null) { string strTip = string.Format("请求 {0} 执行结束!", IntNumber); StateChangeEvent(strTip,IntNumber,true); } } }
运行结果如图:
使用在Winform 项目中,虽然我们没有使用 new Thread()方式创新新线程,并显示指定相应方法在线程中执行,如:
Thread newthread = new Thread(new ThreadStart(function)); newthread.IsBackground = true; newthread.Start();
但最终程序在运行过程中,界面并没有被阻止,说明相应的方法是在线程中去执行的。
我们可以看到线程池会自动帮我们创建相应的新线程,并在线程中执行相应的方法,将运行状态通过自定义事件通知界面,然后界面更新显示