当应用程序终止时,我可以安全地依赖线程中的IsBackground吗?

dr.*_*vil 5 .net multithreading isbackground

我正在GUI中运行一些后台线程.目前我正在实现个人线程取消代码,但线程中有IsBackground属性,根据MSDN,它们将自行取消.

我知道它会变成令人讨厌的Thread.Abort(),但是在这个后台线程中没有任何东西需要保持正确的状态或需要适当的清理.

如果用户只是在后台线程中间关闭应用程序,我试图避免任何崩溃.由于多线程场景很难测试,我想就此主题发表意见.

基本上,我只是设置IsBackground = True而忘记其余的代码而不是滚动我自己的代码?

Chr*_*isF 5

MSDN页面上的IsBackground属性状态:

线程是后台线程或前台线程.后台线程与前台线程相同,除了后台线程不会阻止进程终止.一旦属于进程的所有前台线程终止,公共语言运行库就结束该进程.任何剩余的后台线程都会停止并且不会完成.

所以它意味着我必须让你的线程非常防守,以确保它不会打开任何连接,数据库半写等等.任何关键都需要在前台线程中,这将阻止应用程序关闭直到它完成.


Chr*_*s S 5

乔纳森格林斯特德的帖子有一个很好的总结IsBackground:

IsBackground属性允许您告诉运行时该线程是前台(UI)线程还是后台线程.默认情况下,除非更改此属性,否则所有线程都将创建为前台线程.

那我们为什么要关心呢?

好吧,当最后一个前台线程终止时,.NET运行时会执行一些特殊操作 - 它会中止所有后台线程并终止应用程序.(我们知道Thread.Abort很糟糕,但是如果应用程序正在关闭,那么糟糕的持续时间非常有限.)

换句话说,当应用程序关闭时,后台线程中的工作是否可以在任何时候停止?

如果没有那么它应该是一个前台线程 - 所以一个处理文件句柄或打开数据库连接的线程理想情况下应该是应用程序退出等待该线程在退出之前完成的前台.


Ste*_*dit 4

Thread.Abort 会抛出异常,因此如果您的代码已正确编写为使用finally/using,则它应该优雅地失败并释放所有资源。

编辑

我可能应该提供更多细节。首先,该异常的类型为ThreadAbortException。有趣的是,即使你抓住它但什么也不做,它也不会消失。换句话说,一旦它离开你的 catch 块,它就会继续被抛出。这样,捕获 Exception 并吞掉它的(通常是不好的)做法并不能阻止线程中止。如果您确实想停止中止,则需要捕获异常,然后调用 Thread.ResetAbort。