如果你的应用程序拥有大量的线程并花费大量的时间阻塞在一个Wait Handle上,那么你要考虑使用线程池(Thead pooling)来处理。线程池通过合并多个Wait Handle来节约等待的时间。当Wait Handle被激活时,使用线程池你需要注册一个Wait Handle到一个委托去执行。通过调用ThreadPool.RegisterWaitForSingleObject方法:
class
Test
{
static ManualResetEvent starter = new ManualResetEvent( false );
public static void Main()
{
ThreadPool.RegisterWaitForSingleObject(starter, Go, " hello " , - 1 , true );
Thread.Sleep( 5000 );
Console.WriteLine( " Signaling worker... " );
starter.Set();
Console.ReadLine();
}
public static void Go( object data, bool timedOut)
{
Console.WriteLine( " Started " + data); // Perform task...
}
}
{
static ManualResetEvent starter = new ManualResetEvent( false );
public static void Main()
{
ThreadPool.RegisterWaitForSingleObject(starter, Go, " hello " , - 1 , true );
Thread.Sleep( 5000 );
Console.WriteLine( " Signaling worker... " );
starter.Set();
Console.ReadLine();
}
public static void Go( object data, bool timedOut)
{
Console.WriteLine( " Started " + data); // Perform task...
}
}
对于Wait Handle和委托,RegisterWaitForSingleObject接受一个"黑盒"对象并传递给你的委托(就像ParameterizedThreadStart),超时设置和boolean标志指示了关闭和循环的请求。所有进入池中的线程都被认为是后台线程,这就意味着它们不再由应用程序控制,而是由系统控制直到应用程序退出。
注意:如果这时候调用Abort操作,可能会发生意想不到的情况。
你也可以通过调用QueueUserWorkItem方法使用线程池,指定委托并立即被执行。这时你不能在多任务情况下保存共享线程,但是可以得到另外的好处:线程池会保持一个线程的总容量,当作业数超出容量时自动插入任务。
class
Test
{
static object workerLocker = new object ();
static int runningWorkers = 100 ;
public static void Main()
{
for ( int i = 0 ; i < runningWorkers; i ++ )
{
ThreadPool.QueueUserWorkItem(Go, i);
}
Console.WriteLine( " Waiting for threads to complete... " );
lock (workerLocker)
{
while (runningWorkers > 0 )
Monitor.Wait(workerLocker);
}
Console.WriteLine( " Complete! " );
Console.ReadLine();
}
public static void Go( object instance)
{
Console.WriteLine( " Started: " + instance);
Thread.Sleep( 1000 );
Console.WriteLine( " Ended: " + instance);
lock (workerLocker)
{
runningWorkers -- ;
Monitor.Pulse(workerLocker);
}
}
}
{
static object workerLocker = new object ();
static int runningWorkers = 100 ;
public static void Main()
{
for ( int i = 0 ; i < runningWorkers; i ++ )
{
ThreadPool.QueueUserWorkItem(Go, i);
}
Console.WriteLine( " Waiting for threads to complete... " );
lock (workerLocker)
{
while (runningWorkers > 0 )
Monitor.Wait(workerLocker);
}
Console.WriteLine( " Complete! " );
Console.ReadLine();
}
public static void Go( object instance)
{
Console.WriteLine( " Started: " + instance);
Thread.Sleep( 1000 );
Console.WriteLine( " Ended: " + instance);
lock (workerLocker)
{
runningWorkers -- ;
Monitor.Pulse(workerLocker);
}
}
}
为了传递多个对象到目标方法,你必须定义一个客户对象并包含所有属性或通过调用异步的委托。如Go方法接受两参数:
ThreadPool.QueueUserWorkItem (
delegate
(
object
notUsed) { Go (
23
,
34
); });
其他的方法可以使用异步委托。