为了清楚起见,我简化了下面的例子,但是我在现场制作程序中遇到了这个,我看不出它会如何工作!
public class Test
{
static void Main()
{
Counter foo = new Counter();
ThreadStart job = new ThreadStart(foo.Count);
Thread thread = new Thread(job);
thread.Start();
Console.WriteLine("Main terminated");
}
}
public class Counter
{
public void Count()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Other thread: {0}", i);
Thread.Sleep(500);
}
Console.WriteLine("Counter terminated");
}
}
主程序启动计数器线程,主程序终止。无论给出以下输出,计数器线程都会继续运行。
Main terminated
Other thread: 0
Other thread: 1
Other thread: 2
Other thread: 3
Other thread: 4
Other thread: 5
Other thread: 6
Other thread: 7
Other thread: 8
Other thread: 9
Counter terminated
我的示例程序演示了虽然调用类不再存在,但线程仍然存活完成。但是,我的理解是,一旦一个类超出范围,它的资源最终将被垃圾收集整理。
在我的现实生活场景中,该线程进行了大量的电子邮件持续1-2小时。我的问题是“垃圾收集最终会杀死线程还是GC知道线程仍在处理”?我的电子邮件线程是否会一直运行完成,或者是否存在异常终止的危险?
答案 0 :(得分:12)
答案 1 :(得分:9)
查看System.Threading.Thread.IsBackground
的文档如果一个线程不是后台线程,它将使应用程序不会关闭直到它完成。
答案 2 :(得分:8)
但是,我的理解是,一旦一个类超出范围,它的资源最终将被垃圾收集整理。
这可以更准确地说明:
一旦通过托管引用无法从任何可执行代码访问对象实例,它就有资格进行垃圾回收。
当您创建一个执行特定对象方法的新线程时,您可以在该线程的生命周期内访问该对象的内容。如果GC能够证明任何应用程序的线程不再可能再次访问该对象,则GC只能清理它。由于您的代码 仍然可以访问对象实例,因此它不会获得GCed。
答案 3 :(得分:0)
变量的范围供编译器确定是否可以通过其他方法访问该变量。线程是由运行时控制的运行对象。