我的代码如下:
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”)的线程没有机会完成执行?
答案 0 :(得分:4)
是的,这是正确的。您的主线程在子线程完成之前终止进程 - 或者在某些情况下启动。如果你没有做什么来保持主线程忙,那么当主线程终止时(在“Hi ABC”之后),进程终止将终止所有未完成的线程。如果尚未安排A线程(或任何子线程),则根本没有机会输出。
答案 1 :(得分:2)
如果您不等待任务,则所有四个线程(三个任务加上主线程)同时运行。
由于主线程不需要启动,因此可能首先进入print语句。
答案 2 :(得分:2)
这意味着线程结束或在程序完成后被杀死。你应该添加Console.ReadLine();手动等待,你会看到它们都结束了。
答案 3 :(得分:1)
没有WaitAll
,执行会继续正常进行。在您的上一个Console.WriteLine
之后,应用程序终止,因为它已到达程序的末尾。
答案 4 :(得分:0)
你在这里所谓的“竞争条件”。换句话说,Hello A
,Hello B
,Hello C
和Hi ABC
的顺序是任意的,并且可能会根据首先完成的线程而改变。因此,不同的运行会产生不同的结果。
正在发生的事情是你正在脱离这些线程,然后继续执行程序。在这种情况下,您的竞争条件是哪些线程可以在主执行线程终止(程序结束)之前打印它们的输出。主线程的输出不能保证是第一个,但因为它的启动开销较少,所以它可能是第一个。您可以通过将Task.WaitAll
更改为System.Threading.Thread.Sleep(200)
来测试此问题,并在修改传递到Sleep
方法的毫秒数时查看输出结果。
无需等待,主线程将终止子线程,无论它们处于什么状态。在您提到的情况下,线程B和C已在Console.WriteLine('Hi ABC')
和程序结束之间完成。线程A没有完成,因此它在输出之前被杀死了。