[英]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.