第3章 使用线程池
未完待续
- 在本章中,我们将描述多线程中使用共享资源的常用技术。你将学到以下内容:
- 在线程池中调用委托
- 向线程池中放人异步操作
- 线程池与并行度
- 实现一个取消选项
- 在线程池中使用等待事件处理器及超时
- 使用计时器
- 使用BackgroundWorker组件
3.1 简介
如何只花费极少的时间来完成创建很多异步操作。正如在第1章的简介小节中讨论过的一样,创建线程是昂贵的操作,所以为每个短暂的异步操作创建线程会产生显著的开销。
为了解决该问题,有一个常用的方式叫做池( pooling)。线程池可以成功地适应于任何需要大量短暂的开销大的资源的情形。我们事先分配一定的资源,将这些资源放人到资源池。每次需要新的资源,只需从池中获取一个,而不用创建一个新的。 当该资源不再被使用时,就将其返回到池中。.NET线程池是该概念的一种实现。通过System.Threading.ThreadPool类型可以使用线程池。线程池是受到CLR(运行时)管理的,每个CLR都有一个线程池实例。ThreadPool类型拥有一个QueueUserWorkItem静态方法。该静态方法接受一个委托,代表用户自定义一个异步操作。在该方法被调用后,委托会进入内部队列中。如果池中没任何线程,将创建一个新的工作线程并将队列中第一个委托放入该工作线程中。如果想线程池中放入新的操作,当之前的所有操作完成后,很可能只需要重用一个线程来执行这些新的操作。然后如果放置新的操作过快,线程池将创建更多线程来执行这些操作。创建太多线程是有限制的,在这种情况下新的操作将在队列中等待直到线程池中工作线程有能力来执行他们。注意:保持线程中操作都是短暂的非常重要,不要放入长时间操作,或阻塞工作线程。这样会导致所有工作线程变得繁忙,从而无法服务用户操作,导致性能问题和难以调试。—— 大量地执行那种运行时间短的操作,请使用线程池(较少的线程,比平常更慢速度执行异步操作,则用Thread类自定义线程较为合适)。使用它可以减少并行度耗费及节省操作系统资源。
- 当停止投放,线程池会删除那些过期不再使用的线程,以释放系统资源。
- 线程池中的工作线程都是后台线程。当所有前台线程(包括主程序线程)完成后,所有的后台线程将停止工作。