在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点:

  • 在线程池中调用委托

  • 在线程池中执行异步操作

  • 线程池和并行度

  • 实现取消选项

  • 使用等待句柄和超时

  • 使用计时器

  • 使用后台工作组件

  在前面的“C#多线程之基础篇”以及“C#多线程之线程同步篇”中,我们学习了如何创建线程以及如何使用多线程协同工作,在这一篇中,我们将学习另外一种场景,就是我们需要创建许多花费时间非常短的异步操作来完成某些工作。我们知道创建一个线程是非常昂贵的,因此,对于每个花费时间非常短的异步操作都创建一个线程是不合适的。

  我们可以使用线程池来解决以上问题,我们可以在线程池中分配一定数量的线程,每当我们需要一个线程时,我们只需要在线程池中取得一个线程即可,而不需要创建一个新的线程,当我们使用完一个线程时,我们仅仅需要把线程重新放入线程池中即可。

  我们可以使用System.Threading.ThreadPool类型来利用线程池。线程池由Common Language Runtime(CLR)进行管理,这意味着每一个CLR只能有一个线程池实例。ThreadPool类型有一个“QueueUserWorkItem”静态方法,这个静态方法接收一个委托,该委托代表一个用户自定义的异步操作。当这个方法被调用时,这个委托就进入内部队列,这个时候,如果线程池中没有线程,则会创建一个新的工作线程,然后将这个委托(第一个)放入队列中。

  如果先前的操作执行完毕后,我们又放置了一个新的操作到线程池,那么我们可能会重用上一次操作的那个工作线程。如果我们放置新的操作的时候,线程池中的线程数已达到上限,那么新的操作会在队列中等待,直到线程池中有可用工作线程为止。

  需要注意的是,我们尽量在线程池中放置一些需要花费较少时间既能完成的操作,而不要放置需要花费大量时间才能完成的操作,同时不要阻塞工作线程。如果不是这样,工作线程会变得非常繁忙,以至于不能响应用户操作,同时也会导致性能问题以及难以调试的错误。

  另外,线程池中的工作线程都是