繁体   English   中英

C#无法加入主线程

[英]C# Cannot join main thread

我有非常简单的代码,我无法理解其行为。

class Program
{
    static void Main(string[] args)
    {
        // Get reference to main thread
        Thread mainThread = Thread.CurrentThread;

        // Start second thread
        new Thread(() =>
        {
            Console.WriteLine("Working...");
            Thread.Sleep(1000);

            Console.WriteLine("Work finished. Waiting for main thread to end...");
            mainThread.Join();        // Obviously this join cannot pass

            Console.WriteLine("This message never prints. Why???");
        }).Start();

        Thread.Sleep(300);
        Console.WriteLine("Main thread ended");
    }
}

这个永无止境的程序的输出是:

Working...
Main thread ended
Work finished. Waiting for main thread to end...

为什么线程的代码卡在Join()方法调用上? 通过其他打印输出,可以发现,在Join()调用之前, mainThread IsAlive属性已设置为false,并且ThreadStateBackground, Stopped, WaitSleepJoin 同样,消除睡眠也没有任何区别。

这种行为的原因是什么? Join()方法和Main方法的执行背后有什么奥秘?

Join()可以按您期望的那样工作,这里的问题是假设运行Main()的线程在Main()返回时终止,但情况并非总是如此。

您的Main()方法由.NET框架调用,当该方法返回时,该框架会在主线程(因此进程)退出之前执行其他代码。 具体地说,该框架作为后Main代码的一部分要做的一件事就是等待所有前台线程退出。

这实际上会导致典型的死锁情况-主线程正在等待您的工作线程退出,而工作线程正在等待主线程退出。

当然,如果将工作线程设为后台线程(通过在启动前将IsBackground = true设置),则IsBackground = true代码将不等待其退出,从而消除了死锁。 但是,您的Join() 仍将永远不会返回,因为当主线程退出时,该进程也会退出。

有关在Main()之前和之后运行的框架内部的更多详细信息,您可以查看GitHub上的.NET Core代码库。 运行Main()的整体方法是Assembly::ExecuteMainMethod ,而 Main()返回之后运行的代码是Assembly::RunMainPost

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM