C# 线程池和编程实例
一
线程池可以看做容纳线程的容器;
一个应用程序最多只能有一个线程池;
ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池;
每排入一个工作函数,就相当于请求创建一个线程;
线程池的作用:
线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。
如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。
你可以通过 System.Threading 名称空间的 Thread Pool 类 来使用线程池,如果你查看一下这个类,就会发现所有的成员都是静态的,而且没有公开的构造函数。这是有理由这样做的,因为每个进程只有一个线程池,并且我 们不能创建新的。这个限制的目的是为了把所有的异步编程技术都集中到同一个池中。所以我们不能拥有一个通过第三方组建创建的无法管理的线程池。
二 实例
程序运行结果截图;
码码如下:
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;
//public delegate void WaitCallback(Object state);
namespace ThreadPool1
{
public partial class Form1 : Form
{
static double number1 = -1;
static double number2 = -1;
// 函数变量值
int x = 18808;
public Form1()
{
InitializeComponent();
}
void Draw1(string str1, int xPos = 0, int yPos = 0)
{
SolidBrush aBrush = new SolidBrush(Color.Blue);
Font aFont = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Millimeter);
Graphics graphic = this.CreateGraphics();
graphic.DrawString(str1, aFont, aBrush, xPos, yPos);
}
void ClsFrm()
{
Graphics graphic = this.CreateGraphics();
graphic.Clear(this.BackColor);
}
private void button1_Click(object sender, EventArgs e)
{
int maxThreadNum, portThreadNum;
int minThreadNum;
ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
ClsFrm();
Draw1("最大线程数:" + maxThreadNum.ToString(), 100, 100);
Draw1("最小空闲线程数:" + minThreadNum.ToString(), 100, 130);
}
private void button2_Click(object sender, EventArgs e)
{
// 启动第一个任务:计算x的8次方
ClsFrm();
Draw1("启动第一个任务:计算18808的8次方。", 100, 100);
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);
}
private void button3_Click(object sender, EventArgs e)
{
// 启动第二个任务:计算x的8次方根
ClsFrm();
Draw1("启动第二个任务:计算18808的8次方根。", 100, 100);
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc2), x);
}
private void button4_Click(object sender, EventArgs e)
{
// 等待,直到两个数值都完成计算
while (number1 == -1 || number2 == -1) ;
// 打印计算结果
ClsFrm();
Draw1(number1.ToString() + " " + number2.ToString(), 100, 100);
}
// 启动第一个任务:计算x的8次方
static void TaskProc1(object o)
{
number1 = Math.Pow(Convert.ToDouble(o), 8);
}
// 启动第二个任务:计算x的8次方根
static void TaskProc2(object o)
{
number2 = Math.Pow(Convert.ToDouble(o), 1.0 / 8.0);
}
}
}
代码要点:
引入命名空间:using System.Threading;
这两个函数偶自制,用于在窗体上显示内容和清除显示;
void Draw1(string str1, int xPos = 0, int yPos = 0)
void ClsFrm()
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);
TaskProc1是线程的执行函数,
ThreadPool.QueueUserWorkItem 方法:
将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。
public static bool QueueUserWorkItem(
WaitCallback callBack,
Object state
)
参数:
callBack 类型:System.Threading.WaitCallback WaitCallback ,它表示要执行的方法。
state 类型:System.Object 包含方法所用数据的对象。
返回值 类型:System.Boolean 如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 NotSupportedException。