2012-06-15 2 views
0

내가 코드 아래에있다 : I 구축하고 위의 코드를 실행작업이 수행되지 않은 이유는 무엇입니까?

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"); 
    } 
} 

, 그것은 출력 제공 :
안녕하세요 C
안녕하세요 B
안녕하세요
안녕하세요 ABC에게

을하지만 언급하는 경우 Task.WaitAll (작업), 출력 중 하나입니다 :
안녕하세요 ABC
안녕하세요
안녕하세요

Console.WriteLine ("Hi ABC") 실행이 완료되면 Console.WriteLine ("Hello A")을 실행하는 스레드가 실행을 종료 할 수 없었습니까?

답변

4

네, 맞습니다. 하위 스레드가 완료되기 전에 주 스레드가 프로세스를 종료합니다. 주 스레드를 계속 사용하기 위해 무언가를하지 않으면 주 스레드가 종료되면 ("Hi ABC"이후) 프로세스가 종료되면 모든 처리되지 않은 스레드가 종료됩니다. A 스레드 (또는 임의의 자식 스레드)가 아직 스케줄되지 않은 경우, 전혀 출력 할 기회가 없습니다.

2

작업을 기다리지 않으면 네 개의 스레드 (세 개의 작업과 기본 스레드)가 동시에 실행됩니다.

메인 스레드는 시작할 필요가 없으므로 print 문을 먼저 읽어야합니다.

2

이는 프로그램 종료 후에 스레드가 종료되거나 종료되었음을 의미합니다. Console.ReadLine();을 추가해야합니다. 수동으로 기다리면 모두 끝났음을 알게 될 것입니다.

1

WaitAll이 없으면 실행이 정상적으로 계속됩니다. 마지막 Console.WriteLine 이후에 프로그램이 끝나서 프로그램이 종료됩니다.

0

여기에있는 것은 "경쟁 조건"이라고합니다. 즉, Hello A, Hello B, Hello CHi ABC의 순서는 임의로 지정되며 스레드가 먼저 완료되는 순서에 따라 달라질 수 있습니다. 그래서 다른 실행 결과가 달라질 수 있습니다.

무슨 일이 일어나고 있는지는 이러한 스레드를 돌리고 프로그램 실행을 계속하는 것입니다. 이 경우 경쟁 조건은 주 실행 스레드가 종료 될 때 종료되기 전에 스레드가 출력을 인쇄 할 수있는 것입니다 (프로그램의 끝). 주 스레드의 출력은 처음에는 보장되지 않지만 시작할 때 발생하는 오버 헤드가 적기 때문에 가장 먼저 발생할 가능성이 큽니다. Task.WaitAllSystem.Threading.Thread.Sleep(200)으로 변경하고 Sleep 메소드에 전달하는 밀리 초를 수정할 때 출력이 어떻게되는지 확인하여 테스트 할 수 있습니다.

주 스레드는 기다리지 않고 상태에 관계없이 하위 스레드를 종료합니다. 언급 한 경우 스레드 B와 C가 Console.WriteLine('Hi ABC')과 프로그램 끝 사이에서 완료되었습니다. 스레드 A는 끝내지 않았으므로 출력하기 전에 죽었습니다.

관련 문제