2012-06-15 197 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没有完成,所以它在输出之前就被杀死了。