簡體   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