垃圾收集线程

P D*_*ddy 7 .net multithreading

我是否需要保护Thread垃圾收集器中的对象?包含该线程运行的函数的对象怎么样?

考虑一下这个简单的服

class Server{
    readonly TcpClient client;

    public Server(TcpClient client){this.client = client;}

    public void Serve(){
        var stream = client.GetStream();
        var writer = new StreamWriter(stream);
        var reader = new StreamReader(stream);

        writer.AutoFlush = true;
        writer.WriteLine("Hello");

        while(true){
            var input = reader.ReadLine();
            if(input.Trim() == "Goodbye")
                break;
            writer.WriteLine(input.ToUpper());
        }

        client.Close();
    }
}
static void Main(string[] args){
    var listener = new TcpListener(IPAddress.Any, int.Parse(args[0]));
    listener.Start();

    while(true){
        var client = listener.AcceptTcpClient();
        var server = new Server(client);
        var thread = new Thread(server.Serve);
        thread.Start();
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该将我的线程对象包装在某种静态集合中,以防止它们被垃圾收集器扫除吗?

据推测,如果Thread对象本身保持活动状态,那么该Server对象将存在,因为该线程持有对委托的引用,该委托持有对目标对象的引用.或者可能收集线程对象本身,但实际线程继续运行.现在该Server对象正在进行收集.如果它试图访问其字段会发生什么?

垃圾收集使我的头旋转了一些时间.我很高兴我通常不必考虑它.

考虑到潜在的问题,我想相信垃圾收集器足够聪明,当线程本身仍在执行时不能收集线程对象,但我找不到任何文档说明.反射器在这方面没什么帮助,因为很多Thread类在不出所料的情况下都是在MethodImplOptions.InternalCall函数中实现的.而且我宁愿不通过我过时的旧SSCLI副本来寻找答案(因为这是一个痛苦,因为它不是一个肯定的答案).

Al *_*epp 6

这很简单.真正的执行线程不是Thread对象.该程序在真正的Windows线程中执行,无论.NET垃圾收集器对您的Thread对象执行什么操作,它都会保持活动状态.所以对你来说是安全的; 如果只是希望程序继续运行,则不需要关心Thread对象.

另请注意,您的线程在运行时不会被收集,因为它们实际上属于应用程序"根".(Roots - 垃圾收集器知道什么是活着的.)

更多细节:托管的Thread对象可以通过Thread.CurrentThread- 这类似于全局静态变量而不会被收集.正如我之前所写:任何已启动并且现在正在执行任何代码(甚至在.NET之外)的托管线程都不会丢失其Thread对象,因为它与"根"紧密相连.