将.Net Garbage收集一个未被引用的对象,但是有一个正在运行的线程吗?

Dam*_*isa 6 .net c# multithreading garbage-collection

我有以下代码(为了便于阅读而减少):

主类:

public StartProcess()
{
    Thinker th = new Thinker();
    th.DoneThinking += new Thinker.ProcessingFinished(ThinkerFinished);
    th.StartThinking();
}

void ThinkerFinished()
{
    Console.WriteLine("Thinker finished");
}
Run Code Online (Sandbox Code Playgroud)

思想家班级:

public class Thinker
{
    private System.Timers.Timer t;

    public delegate void ProcessingFinished();
    public event ProcessingFinished DoneThinking;

    BackgroundWorker backgroundThread;

    public Thinker() { }

    public StartThinking()
    {
        t = new System.Timers.Timer(5000);    // 5 second timer
        t.AutoReset = false;
        t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
        t.Start();

        // start a background thread to do the thinking
        backgroundThread = new BackgroundWorker();
        backgroundThread.DoWork += new DoWorkEventHandler(BgThread_DoWork);
        backgroundThread.RunWorkerAsync();
    }

    void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        DoneThinking();
    }

    BgThread_DoWork(object sender, DoWorkEventArgs e)
    {
        // work in here should go for much less than 5 seconds
        // it will die if it doesn't

        t.Stop();
        DoneThinking();
    }
}
Run Code Online (Sandbox Code Playgroud)

我最初预计会发生的事情是主类中的事件处理程序会阻止Thinker被垃圾回收.

显然事实并非如此.

我现在想知道无论这个线程是否"忙",是否会发生垃圾收集.换句话说,是否有可能在5秒超时到期之前收集垃圾?

换句话说,垃圾收集器是否有可能在完成处理之前收集我的Thinker?

oll*_*iej 9

不,一个线程被认为是活动的,只要它被引用,并且任何正在运行的线程都被认为是被引用的(IIRC,一个正在运行的线程将其堆栈注册为GC根,并且该堆栈将引用该线程).

那说我正在看你的例子,我不明白你认为一个线程在哪里产生?


Kev*_*ose 5

不,正在运行的线程的堆栈充当GC的根.只要线程正在运行,该堆栈就会存在,因此线程本身不会在其运行时收集.

这里有一个文章是提到(除其他事项外)什么的根源是GC的目的.为了节省一些时间,GC根是全局对象,静态对象,所有线程堆栈上的所有引用,以及包含引用的所有CPU寄存器.