我一直在阅读多线程应用程序的代码和示例。我不时会看到一个类似的片段:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("started");
Go();
Console.WriteLine("press [ENTER] to quit");
Console.ReadLine();
}
private static void Go()
{
var thread = new Thread(DoSomething);
thread.Start();
}
private static void DoSomething()
{
Console.WriteLine("doing something");
}
}
它一直困扰着我:我应该在某处保留对(前景)线程的引用吗?毕竟,它是Go
方法中的局部变量。因此,一旦Go
的执行完成,线程引用应该被垃圾收集。也许,也许,也许,线程将在执行时进行GC?
如果答案是背景话题,答案是否会改变?
提前致谢!
答案 0 :(得分:4)
线程是一个对象的一个示例,其生存期不由垃圾收集器控制。它是一个操作系统对象。只要线程正在运行代码,那就是活着的。 Thread类只是它的包装器。另一个例子是一个窗口,只要您的代码或用户不关闭它,它就会存活。 Winforms不要求您持有对Form类包装器的引用。你通常不这样做:
Application.Run(new Form1());
是锅炉板代码,您不会在任何地方持有对Form1类实例的引用。
您始终可以从现有正在运行的线程重新创建Thread对象。您可以使用Thread.CurrentThread执行此操作。它不必是您使用Thread构造函数创建的线程。它可以在线程池线程中使用。或者是托管代码未启动的线程。你的程序的主线程就是一个很好的例子,它是由Windows启动的。
尽管如此,丢失对线程的引用并不是一种好的做法。这意味着您无法检查它是否仍在运行。这意味着当它应该停止时你无法阻止它。例如,当用户想要退出程序时。
答案 1 :(得分:2)
根据this answer,您无需担心。 GC足够聪明,可以知道是否正在使用线程。
这是一篇解释行为的文章:http://msdn.microsoft.com/en-us/magazine/bb985011.aspx#ctl00_MTContentSelector1_mainContentContainer_ctl03
答案 2 :(得分:2)
如果您想稍后使用它,您只需要保留该引用。在这种情况下,垃圾收集在线程完成之前不会启动。
前台线程和后台线程之间的唯一区别是前台线程使托管执行环境保持运行。
这意味着正在运行的前台线程将阻止您的应用程序关闭,而后台线程则不会。