C#3.0核心技术-第19章线程-全新翻译注释-19.2(5)

来源:互联网 发布:数据库测试用例怎么写 编辑:程序博客网 时间:2024/04/30 12:19

19.2.4 前台和后台线程

缺省地,你明确创建的线程是前台线程;线程池线程是后台线程。区别在于只要前台线程们中任何一个正在运行就可以保持应用程序的存活;后台线程不会这样。一旦所有的前台线程结束,应用程序终止,任何仍旧在运行的后台线程突然终止。

原文注:

一个线程的前台/后台状态与它的优先权或者执行时间的分配没有关系。

你能够使用线程的IsBackground属性查询或者改变一个线程后台状态。这里是一个例子:

clip_image001

如果这个程序被调用的时候没有参数,worker线程呈现前台状态并且在ReadLine语句上等待用户按下Enter键。同时,主线程退出,但是应用程序保持运行因为一个前台线程(译者注:即worker线程)仍旧是存活的。

另一方面,如果一个参数被赋予Main(),worker(译者注:线程)被赋予后台状态,程序由于主线程终止而几乎立即退出(终止了ReadLine)。

当一个后台线程以这种方式终止,任何finally块被规避。这是一个问题如果你的程序使用finally块(或者using关键字)执行诸如释放资源或者删除临时文件的清除工作。为避免这一点,你可以在退出一个应用程序时明确地等待这个后台线程。这里有两种方式做到这一点:

如果是你自己创建的线程,调用Join方法在这个线程上。

如果你正在使用线程池,使用一个事件等待句柄(event wait handle)(在本章后面的19.8节中讨论)

在任一个情况中,你最好指定一个超时,使得你能够抛弃一个叛逆的线程,这个线程因为某种原因而拒绝结束。这是你的备用的退出策略:在最后,你希望你的应用程序关闭—而无需用户不得不从Task Manager中征用帮助!

原文注:

如果一个用户使用Task Manager强迫终止一个.NET进程,所有的线程像它们是后台线程一样“倒毙”。这是被观察到的行为,而不是文档中所记录的行为,并且它能够依据CLR和操作系统版本的不同而不同。

前台线程不需要这种待遇(译者注:指为了避免后台线程突然终止而采取的措施),但是你必须小心地避免能够导致线程不终止的bug。一个应用程序不能正确退出的共同原因是活动前台线程的出现。