为什么任务没有执行?

时间:2012-06-15 21:00:37

标签: c# multithreading task

我的代码如下:

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
你好A
你好ABC

但如果我评论Task.WaitAll(任务),其中一个输出是:
你好ABC 你好B
你好C

这是否意味着当Console.WriteLine(“Hi ABC”)完成执行时,执行Console.WriteLine(“Hello A”)的线程没有机会完成执行?

5 个答案:

答案 0 :(得分:4)

是的,这是正确的。您的主线程在子线程完成之前终止进程 - 或者在某些情况下启动。如果你没有做什么来保持主线程忙,那么当主线程终止时(在“Hi ABC”之后),进程终止将终止所有未完成的线程。如果尚未安排A线程(或任何子线程),则根本没有机会输出。

答案 1 :(得分:2)

如果您不等待任务,则所有四个线程(三个任务加上主线程)同时运行。

由于主线程不需要启动,因此可能首先进入print语句。

答案 2 :(得分:2)

这意味着线程结束或在程序完成后被杀死。你应该添加Console.ReadLine();手动等待,你会看到它们都结束了。

答案 3 :(得分:1)

没有WaitAll,执行会继续正常进行。在您的上一个Console.WriteLine之后,应用程序终止,因为它已到达程序的末尾。

答案 4 :(得分:0)

你在这里所谓的“竞争条件”。换句话说,Hello AHello BHello CHi ABC的顺序是任意的,并且可能会根据首先完成的线程而改变。因此,不同的运行会产生不同的结果。

正在发生的事情是你正在脱离这些线程,然后继续执行程序。在这种情况下,您的竞争条件是哪些线程可以在主执行线程终止(程序结束)之前打印它们的输出。主线程的输出不能保证是第一个,但因为它的启动开销较少,所以它可能是第一个。您可以通过将Task.WaitAll更改为System.Threading.Thread.Sleep(200)来测试此问题,并在修改传递到Sleep方法的毫秒数时查看输出结果。

无需等待,主线程将终止子线程,无论它们处于什么状态。在您提到的情况下,线程B和C已在Console.WriteLine('Hi ABC')和程序结束之间完成。线程A没有完成,因此它在输出之前被杀死了。