2012-06-15 195 views
0

我有下面的代碼:爲什麼任務沒有執行?

class Program 
{ 
    static void Main(string[] args) 
    { 

     Task[] tasks = new Task[3] 
         { 
          Task.Factory.StartNew(() => Console.WriteLine("Hello A")), 
          Task.Factory.StartNew(() => Console.WriteLine("Hello B")), 
          Task.Factory.StartNew(() => Console.WriteLine("Hello C")) 
         }; 
     Task.WaitAll(tasks); 
     Console.WriteLine("Hi ABC"); 
    } 
} 

我建立並運行上面的代碼,它給輸出:
您好ç
你好乙
你好一個
ABC嗨

但如果我評論Task.WaitAll(任務),其中一個輸出是:
嗨ABC
你好B
你好C

這是否意味着當Console.WriteLine(「嗨ABC」)執行完畢,線程,其執行Console.WriteLine(「你好A」)沒有得到一個機會來完成執行?

回答

4

是的,這是正確的。您的主線程正在終止子線程完成之前的進程 - 或者在某些情況下啓動。如果你不做任何事情來保持主線程忙,那麼當主線程終止時(在「Hi ABC」之後),進程終止將會終止所有未完成的線程。如果A線程(或任何子線程)尚未安排,那麼它根本就沒有機會輸出。

2

如果沒有等待的任務,所有四個同時運行的線程(三個任務加上主線程)的。

由於主線程不需要啓動,很可能去的print語句第一。

2

這意味着線程結束或它在程序結束後被殺死。你應該添加Console.ReadLine();手動等待,你會看到他們都結束了。

1

沒有WaitAll,執行正常繼續。在最後一個Console.WriteLine之後,應用程序因爲到達程序結束而終止。

0

你在這裏所擁有的是什麼被稱爲「競賽條件」。換句話說,在Hello AHello BHello C,並Hi ABC的順序是任意的,並且可以改變,這取決於線程完成第一。所以不同的運行可能產生不同的結果

發生了什麼事是你分拆這些線程,然後繼續執行程序。在這種情況下,競爭條件是哪些線程可以在主執行線程死亡(程序結束)中斷之前打印它們的輸出。主線程的輸出不能保證是第一個,但是因爲它的啓動開銷較小,所以它很可能是第一個。您可以通過將Task.WaitAll更改爲System.Threading.Thread.Sleep(200)並在修改傳遞給Sleep方法的毫秒時查看輸出結果。

無需等待,主線程會終止子線程,而不管它們處於什麼狀態。如果您提到,B和C線程已在Console.WriteLine('Hi ABC')和程序結束之間完成。線程A沒有完成,所以它在輸出之前就被殺死了。