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,ThreadState
为Background, Stopped, WaitSleepJoin
。删除睡眠也没有任何区别。
这种行为的原因是什么? Join()
方法和 Main
方法的执行背后有什么奥秘?
Join()
按照您的预期工作,这里的问题是假设线程 运行ning Main()
在 Main()
return 时终止s,但情况并非总是如此。
您的 Main()
方法由 .NET 框架调用,当方法 returns 时,框架在主线程(以及进程)退出之前执行额外的代码.具体来说,框架作为 post-Main 代码的一部分所做的事情之一是等待所有前台线程退出。
这基本上会导致典型的死锁情况 - 主线程正在等待您的工作线程退出,而您的工作线程正在等待主线程退出。
当然,如果你让你的工作线程成为后台线程,(通过在启动它之前设置 IsBackground = true
)然后 post-Main 代码不会等待它退出,消除僵局。但是,您的 Join()
将 仍然 永远不会 return 因为当主线程退出时,进程也会退出。
有关 运行 在 Main()
之前和之后的框架内部的更多详细信息,您可以查看 GitHub 上的 .NET Core 代码库。 运行s Main()
的整体方法是Assembly::ExecuteMainMethod
, and the code that runs after Main()
returns is Assembly::RunMainPost
.
我有非常简单的代码,但我无法理解其行为。
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()
按照您的预期工作,这里的问题是假设线程 运行ning Main()
在 Main()
return 时终止s,但情况并非总是如此。
您的 Main()
方法由 .NET 框架调用,当方法 returns 时,框架在主线程(以及进程)退出之前执行额外的代码.具体来说,框架作为 post-Main 代码的一部分所做的事情之一是等待所有前台线程退出。
这基本上会导致典型的死锁情况 - 主线程正在等待您的工作线程退出,而您的工作线程正在等待主线程退出。
当然,如果你让你的工作线程成为后台线程,(通过在启动它之前设置 IsBackground = true
)然后 post-Main 代码不会等待它退出,消除僵局。但是,您的 Join()
将 仍然 永远不会 return 因为当主线程退出时,进程也会退出。
有关 运行 在 Main()
之前和之后的框架内部的更多详细信息,您可以查看 GitHub 上的 .NET Core 代码库。 运行s Main()
的整体方法是Assembly::ExecuteMainMethod
, and the code that runs after Main()
returns is Assembly::RunMainPost
.