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

我构建并运行上面的代码,它给出了输出:
Hello C
Hello B
Hello A
Hi ABC

但如果我评论 Task.WaitAll(tasks),输出之一是:
Hi ABC
Hello B
Hello C

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

4

5 回答 5

4

对,那是正确的。您的主线程在子线程完成之前终止进程 - 或在某些情况下启动。如果你不做任何事情来保持主线程忙碌,那么当主线程终止时(在“Hi ABC”之后),进程终止将杀死所有未完成的线程。如果 A 线程(或任何子线程)还没有被调度,那么它根本没有机会输出。

于 2012-06-15T21:03:41.620 回答
2

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

由于主线程不需要启动,它很可能首先到达 print 语句。

于 2012-06-15T21:02:51.750 回答
2

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

于 2012-06-15T21:03:48.200 回答
1

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

于 2012-06-15T21:03:57.393 回答
0

您在这里拥有的是所谓的“竞争条件”。换句话说, 、 、 和 的顺序Hello AHello B任意Hello CHi ABC,并且可以根据哪个线程先完成而改变。所以不同的运行可能会产生不同的结果。

发生的事情是您正在关闭这些线程,然后继续执行程序。在这种情况下,您的竞争条件是哪些线程可以在主执行线程死亡(程序结束)被杀死之前打印它们的输出。主线程的输出不能保证是第一个,但是因为它从启动开始的开销较小,所以它很可能是第一个。Task.WaitAll您可以通过将 更改为 a来测试这一点,并在修改传递给该方法System.Threading.Thread.Sleep(200)的毫秒数时查看输出结果。Sleep

无需等待,主线程就会杀死子线程,无论它们处于何种状态。在您提到的情况下,线程 B 和 C 已Console.WriteLine('Hi ABC')在程序结束之间完成。线程 A 没有完成,所以它还没来得及输出就被杀死了。

于 2012-06-15T21:10:17.787 回答