首页 > 代码库 > 线程学习笔记 等待句柄和线程池(摘自https://blog.gkarch.com/threading/part2.html#manualresetevent)

线程学习笔记 等待句柄和线程池(摘自https://blog.gkarch.com/threading/part2.html#manualresetevent)

//如果你的应用有很多线程,这些线程大部分时间都在阻塞,那么可以通过调用ThreadPool.RegisterWaitForSingleObject来减少资源消耗。这个方法接受一个委托,它会在向等待句柄发信号时执行。当处于等待状态时,它不会浪费线程资源:
static ManualResetEvent _starter = new ManualResetEvent (false);

public static void Main()
{
  RegisteredWaitHandle reg = ThreadPool.RegisterWaitForSingleObject
                             (_starter, Go, "Some Data", -1, true);
  Thread.Sleep (5000);
  Console.WriteLine ("Signaling worker...");
  _starter.Set();
  Console.ReadLine();
  reg.Unregister (_starter);    // 完成后的清理
}

public static void Go (object data, bool timedOut)
{
  Console.WriteLine ("Started - " + data);
  // 执行任务 ....
}
输出结果:
(5 second delay)
Signaling worker...
Started - Some Data
//当向等待句柄发信号时(或者已超时),委托会在一个线程池线程运行。
//除等待句柄和委托外,RegisterWaitForSingleObject还接受一个“黑盒”对象,它会被传递给委托的目标方法(像ParameterizedThreadStart一样);还有一个以毫秒为单位的超时时间(-1 代表没有超时时间);和一个布尔值用来设置请求是一次性的还是可重复的。
RegisterWaitForSingleObject在需要处理很多并发请求的应用服务器中非常有用。假如你需要在ManualResetEvent上阻塞,调用WaitOne就可以了:
void AppServerMethod()
{
  _wh.WaitOne();
  // ... 继续执行
}
//如果 100 个客户端调用这个方法,就会有 100 个服务端线程被浪费在阻塞上。把_wh.WaitOne换成RegisterWaitForSingleObject可以让方法立即返回,就不会浪费线程资源:
void AppServerMethod
{
  RegisteredWaitHandle reg = ThreadPool.RegisterWaitForSingleObject
   (_wh, Resume, null, -1, true);
  // ...
}

static void Resume (object data, bool timedOut)
{
  // ... 继续执行
}

 

线程学习笔记 等待句柄和线程池(摘自https://blog.gkarch.com/threading/part2.html#manualresetevent)