[英]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,并且ThreadState
为Background, 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.