我在 GUI 中运行一些后台线程。目前我正在实现个人线程取消代码,但线程中有 IsBackground 属性,根据 MSDN,他们会自行取消。
我知道它会去 Thread.Abort() 这很讨厌,但是在这个后台线程中没有任何事情需要我保持适当的状态或需要适当的清理。
如果用户只是在后台线程中间关闭应用程序,我会尽量避免任何崩溃。由于多线程场景很难测试,我想听听您对这个主题的看法。
基本上,我应该设置 IsBackground = True 而不是滚动我自己的代码,而忘记其余的?
我在 GUI 中运行一些后台线程。目前我正在实现个人线程取消代码,但线程中有 IsBackground 属性,根据 MSDN,他们会自行取消。
我知道它会去 Thread.Abort() 这很讨厌,但是在这个后台线程中没有任何事情需要我保持适当的状态或需要适当的清理。
如果用户只是在后台线程中间关闭应用程序,我会尽量避免任何崩溃。由于多线程场景很难测试,我想听听您对这个主题的看法。
基本上,我应该设置 IsBackground = True 而不是滚动我自己的代码,而忘记其余的?
该物业上的MSDN 页面IsBackground
指出:
线程要么是后台线程,要么是前台线程。后台线程与前台线程相同,只是后台线程不会阻止进程终止。一旦属于一个进程的所有前台线程都已终止,公共语言运行时就会结束该进程。任何剩余的后台线程都将停止并且不会完成。
所以这对我来说意味着你必须让你的线程非常防御,以确保它不会留下任何打开的连接、半写的数据库等。任何关键的东西都需要在前台线程中,以防止应用程序关闭直到完成。
Jonathan Greensted 的帖子有一个很好的总结IsBackground
:
IsBackground 属性允许您告诉运行时线程是前台 (UI) 线程还是后台线程。默认情况下,所有线程都创建为前台线程,除非您更改此属性。
那么我们为什么要关心呢?
好吧,当最后一个前台线程终止时,.NET 运行时会做一些特殊的事情——它中止所有后台线程并终止应用程序。(我们知道 Thread.Abort 很糟糕,但是如果应用程序无论如何都被关闭,那么糟糕的持续时间非常有限。)
换句话说,后台线程中正在完成的工作是否可以在应用程序关闭时随时停止?
如果不是,那么它可能应该是一个前台线程 - 因此使用文件句柄或打开数据库连接的线程理想情况下应该是前台,应用程序退出将在退出之前等待该线程完成。
Thread.Abort 会引发异常,因此如果您的代码已经正确编写为使用 finally/using,它应该会正常失败并释放所有资源。
编辑
我可能应该提供更多细节。首先,异常类型为 ThreadAbortException。有趣的是,即使你抓住它,什么也不做,它也不会消失。换句话说,一旦它离开你的 catch 块,它就会继续被抛出。这样一来,捕获异常并吞下它的(通常是不好的)做法不会阻止线程中止。如果您确实想停止中止,则需要捕获异常,然后调用 Thread.ResetAbort。
我认为这取决于资源。例如,套接字在进程结束时安全关闭。对于某些资源,您最好在退出线程之前释放它。