如何在调用进程退出或被杀死时优雅地结束线程?

时间:2013-06-13 19:44:51

标签: c# multithreading garbage-collection finalizer

所以我想的是一个类的实例,我想让一个线程在类的生命周期中运行,但是当调用该类的进程不再运行时终止。这不是父线程终止子进程的情况,而是单个旋转(在等待循环中)线程正常退出而不保留资源等。

我认为在C ++中,你可以告诉线程使用析构函数中的volatile bool来终止,但是在C#中,〜不是析构函数,它是终结器。我无法使用终结器成功终止线程。也许我错过了一些东西。我知道更好的做法是让所有线程死于自然死亡而不发出信号终止,但每次我需要做某事时产生一个线程效率都不高。是的我知道线程池,但我认为让一个侦听器线程响应对类的调用会更好,并且当类放在gc上时它会优雅地死掉。

真正的诀窍是,我想,我可以知道,或者我怎么知道什么时候运行该线程的类首先放在gc上。 IDisispos是我想要的吗?我这里没有使用任何非托管代码。

1 个答案:

答案 0 :(得分:5)

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

选择一:

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

如果您正在使用具有应该调用的dispose方法的对象,则只需要担心。这包括打开文件,但可能不会包含类似字体的内容。

如果你这样做,你必须确保该线程将作为"背景"线。后台线程和前台线程之间的唯一区别是,当程序关闭时,所有后台线程都将自动终止 - 但前台线程不会赢。

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

如果您的线程正在执行某些IO到磁盘或执行其他任何不会被中断的事情,那么您肯定赢得想要这样做。

选择二:

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

在这种情况下,您不会非常关心线程是前台还是后台,因为您将自己管理程序关闭,并且线程将在程序退出之前正确停止。

如果采用此路由,则可以将线程取消逻辑和其他线程处理方法封装在包装线程的类中。然后,您可以添加Dispose()方法,以便在using块内创建类,以确保即使在异常情况下也能正常关闭。

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