当原始类超出范围时,线程会发生什么

Mor*_*Cat 16 .net c# multithreading

为了清楚起见,我简化了下面的例子,但我在现场制作程序中遇到了这个,我看不出它会如何工作!

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

主程序启动计数器线程,主程序终止.无论给出以下输出,计数器线程都会继续运行.

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
Run Code Online (Sandbox Code Playgroud)

我的示例程序演示了虽然调用类不再存在,但线程仍然存活完成.但是,我的理解是,一旦一个类超出范围,它的资源最终将被垃圾收集整理.

在我的现实生活场景中,线程进行了大量的电子邮件持续1-2小时.我的问题是"垃圾收集最终会杀死线程还是GC知道线程仍在处理"?我的电子邮件线程是否会一直运行完成,或者是否存在异常终止的危险?

xan*_*tos 14

来自System.Threading.Thread

一旦启动线程,就不必保留对Thread对象的引用.线程继续执行,直到线程过程完成.

因此,即使Thread对象未被引用,线程仍将运行.


adv*_*v12 9

查看System.Threading.Thread.IsBackground的文档

如果一个线程不是后台线程,它将使应用程序不会关闭直到它完成.


Ser*_*rvy 9

但是,我的理解是,一旦一个类超出范围,它的资源最终将被垃圾收集整理.

这可以更精确地说明:

一旦通过托管引用无法从任何可执行代码访问对象实例,它就有资格进行垃圾回收.

当您创建一个执行特定对象方法的新线程时,您可以在该线程的生命周期内访问该对象的内容.如果GC能够证明任何应用程序的线程不再可能再次访问该对象,则GC只能清理它.由于您的代码仍然可以访问对象实例,因此它不会获得GCed.