首先,看看线程池的样子:
从上图看出,线程池维护1个至n个线程,操作系统从请求队列中提取请求分配个线程池中的适合线程处理。
先写下如下的代码:
using
System;
using
System.Threading;
public
class
ThreadBase
{
public static void Main ( )
{
System.Threading.WaitCallback waitCallback = new WaitCallback ( MyThreadWork );
ThreadPool.QueueUserWorkItem ( waitCallback, "第一个线程" );
ThreadPool.QueueUserWorkItem ( waitCallback, "第二个线程" );
ThreadPool.QueueUserWorkItem ( waitCallback, "第三个线程" );
ThreadPool.QueueUserWorkItem ( waitCallback, "第四个线程" );
Console.ReadLine ( );
}

public static void MyThreadWork ( object state )
{
Console.WriteLine ( "线程现在开始启动…… {0}",(string)state );
Thread.Sleep ( 10000 );
Console.WriteLine ( "运行结束…… {0}",( string ) state );
}
}
分析上面的代码:
一、首先定义了一个 System.Threading.WaitCallback 对象 waitCallback。
WaitCallback 是一个委托,表示线程池线程要执行的回调方法,它的原型如下:
[ComVisibleAttribute(
true
)]
public
delegate
void
WaitCallback (
Object state
)
1、这里有一个 Callback 机制的问题,所谓的Callback 简单的理解就是由操作系统调用的函数,我们自己写的程序不需要调用。就像有个修理工到家里搞修理,你只需要告诉他钳子、螺丝刀、胶布等修理工具在什么地方就行,而不要管他在什么时候、在什么地方怎样使用这些修理工具。
2、WaitCallback 的参数" Object state",这个参数包含回调方法要使用的信息的对象。在接下来的情况中我再说。
既然 WaitCallback 委托的原型如此,那么我们就申明一个跟它的样子差不多的函数,这个函数就是要线程做的事情。
public
static
void
MyThreadWork (
object
state )
这里函数中多了一个 "static",这是因为Main的关系(更大一点就是因为C#语言机制的问题),如果WaitCallback 的对象不是在静态(static)方法中,这个static 是不需要的。
二、接着就是要执行的方法放入线程池中,以便操作系统执行。
我这里放置了四个方法要操作系统执行:
ThreadPool.QueueUserWorkItem ( waitCallback,
"
第一个线程
"
);
ThreadPool.QueueUserWorkItem ( waitCallback,
"
第二个线程
"
);
ThreadPool.QueueUserWorkItem ( waitCallback,
"
第三个线程
"
);
ThreadPool.QueueUserWorkItem ( waitCallback,
"
第四个线程
"
);
这里,我放置到线程池中的操作是一样的,当然也可以不一样,接下来说。
三、最后阻塞主线程,等待线程池中的线程执行
Console.ReadLine ( );
如果忽略掉这个代码,则有可能看不到任何输出
好了,这是主线程做的事情了,接下来看看线程池中的线程做的事情。
这个很简单,就是将线程的参数输出,然后线程睡眠(sleep)一段时间,最后输出线程结束的信息。
|
我们可以通过Thread类,一次使用一个线程,来创建和删除线程。这种方式建立和删除线程是很昂贵的(cpu密集型)。所以,CLR包含一个内置的线程池,供应用程序使用。这个线程池可以通过ThreadPool类访问。
ThreadPool类会在线程的托管池中重用已有的线程。使用完线程后,线程就会返回线程池,供以后使用。ThreadPool有25个可用的线程(每个处理器)。
使用ThreadPool类比Thread类创建线程简单的多。但是,在确定是用ThreadPool类还是Thread类创建线程时,考虑如下问题:
在达到如下目标时,应使用ThreadPool类:
要以最简单的方式创建和删除线程;
应用程序使用线程的性能要优先考虑。
在达到如下目标时,应使用Thread类:
要控制所创建线程的优先级;
希望所使用的线程维护其标识,该标识要与线程一起进行各种操作,经过许多不同的时间段;
所使用的线程的寿命较长。
ThreadPool的调用需要调用ThreadPool.QueueUserWorkItem()方法。调用这个方法有两种方式。一种是:
ThreadPool.QueueUserWorkItem(new WailtCallback(StartMethod));
二是:
ThreadPool.QueueUserWorkItem(StartMethod); 如果需要认为增加最大线程数目,ThreadPool.SetMaxThreads |
线程池本身是为较小、迅速的,的大量任务而提供的,
如果处理的东西对占用很长时间,建议换成Thread,手动控制
ThreadPool..::.QueueUserWorkItem 方法 (WaitCallback)
http://technet.microsoft.com/zh-tw/kbf0f1ct(zh-cn,VS.95).aspx
C#线程池与ThreadPool类详解
本文详细解析了C#中线程池的概念、线程池与Thread类的区别,以及如何使用ThreadPool.QueueUserWorkItem方法将工作项放入线程池中执行,并讨论了在何种情况下应该使用ThreadPool类或Thread类。
3598

被折叠的 条评论
为什么被折叠?



