如何在调用进程退出或终止时优雅地结束线程?

本文关键字:结束 线程 终止 调用 进程 退出 | 更新日期: 2023-09-27 18:18:31

所以我正在考虑一个类的实例,我希望一个线程在类的生命周期内运行,但在调用类的进程不再运行时终止。这不是父线程终止子线程的情况,而是单个旋转线程(可能在等待循环中)优雅地退出,而不占用资源等。

我认为在c++中,你可以通过析构函数中的volatile bool值告诉线程终止,但是在c#中,~不是析构函数,而是终结器。我无法使用终结器成功终止线程。也许我遗漏了什么。我知道更好的做法是让所有线程自然死亡而不发出终止信号,但是每次我需要做某事时都生成一个线程是不有效的。是的,我知道线程池,但我认为最好有一个侦听器线程响应对类的调用,并让它在类被放入gc时优雅地死亡。

我认为,真正的技巧是,我能知道,或者我如何知道运行线程的类是什么时候第一次放在gc上的。我要的是一次性的吗?这里我没有使用任何非托管代码。

如何在调用进程退出或终止时优雅地结束线程?

我认为你基本上有两个明智的选择。

选择

:

如果你真的没有任何非托管的资源在使用,那么你可以让系统在程序关闭时关闭你的线程。这显然是最简单的解决办法。

你只需要担心如果你使用的对象有应该被调用的dispose方法。这包括打开的文件,但可能不包括像字体这样的东西。

如果你这样做,你必须确保线程将作为"后台"线程运行。后台线程和前台线程的唯一区别是,当程序关闭时,所有后台线程将自动终止——但前台线程不会。

如果您使用Task,默认情况下它将作为后台线程运行。

你肯定不会想要这样做,如果你的线程将做一些IO磁盘或做任何其他不能被中断。

选择二:

添加一个线程取消机制,使用CancellationTokenSource并安排在程序关闭时使用它,并等待线程退出。

在这种情况下,你不会真正关心线程是前台还是后台,因为你将自己管理程序关闭,并且线程将在程序退出之前被适当地停止。

如果你采用这种方法,你可以将线程取消逻辑和其他线程处理方法封装在一个封装线程的类中。然后你可以添加一个Dispose()方法,这样你就可以在using块中创建类,以确保即使在面对异常时也能正确关闭。

我经常使用这种方法,而且看起来效果很好。