简体   繁体   English

为什么任务没有执行?

[英]Why task didn't perform?

I have below code: 我有以下代码:

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

I build and run the above code, it gives output: 我构建并运行上面的代码,它给出了输出:
Hello C 你好ç
Hello B 你好乙
Hello A 你好A
Hi ABC 嗨,ABC

But if I comment Task.WaitAll(tasks), one of the outputs is: 但是,如果我评论Task.WaitAll(tasks),输出之一是:
Hi ABC 嗨,ABC
Hello B 你好乙
Hello C 你好ç

Does it mean when Console.WriteLine("Hi ABC") finishes execution, thread which executes Console.WriteLine("Hello A") didn't get a chance to finish execution? 这是否意味着当Console.WriteLine(“ Hi ABC”)完成执行时,执行Console.WriteLine(“ Hello A”)的线程没有机会完成执行?

Yes, that's correct. 对,那是正确的。 Your main thread is terminating the process before the child threads have finished - or started in some cases. 您的主线程在子线程完成(或在某些情况下开始)之前终止进程。 If you don't do something to keep the main thread busy, then when the main thread terminates (after "Hi ABC"), the process termination will kill all outstanding threads. 如果您不做任何事情来保持主线程繁忙,那么当主线程终止时(“ Hi ABC”之后),进程终止将杀死所有未完成的线程。 If the A thread (or any of the child threads) hasn't been scheduled yet, then it won't have a chance to output at all. 如果尚未安排A线程(或任何子线程),则根本没有机会输出。

If you don't wait for the tasks, all four of your threads (three tasks plus the main thread) run at the same time. 如果您不等待任务,那么所有四个线程(三个任务加上主线程)将同时运行。

Since the main thread doesn't need to start up, it's likely to get to the print statement first. 由于主线程不需要启动,因此很可能先进入print语句。

It means that the Thread ends or that it got killed after the Program has finished. 这意味着线程结束或在程序完成后被杀死。 You should add Console.ReadLine(); 您应该添加Console.ReadLine();。 to wait manually and you will see that they all end. 手动等待,您将看到它们都结束了。

Without the WaitAll , the execution continues normally. 没有WaitAll ,执行将继续正常进行。 After your last Console.WriteLine , the application terminates because it's reached the end of the program. 在最后一个Console.WriteLine ,该应用程序终止,因为它已到达程序末尾。

What you have here is what is known as a "race condition". 您在这里拥有的就是所谓的“比赛条件”。 In other words, the order of the Hello A , Hello B , Hello C , and Hi ABC is arbitrary, and could change depending on which thread finishes first. 换句话说, Hello AHello BHello CHi ABC的顺序是任意的,并且可以根据哪个线程首先完成而改变。 So different runs could yield different results. 因此,不同的运行可能会产生不同的结果。

What's happening is that you are spinning off these threads, then continuing execution of the program. 发生的情况是您正在分离这些线程,然后继续执行程序。 In this case, your race condition is which threads can print their output before being killed off as the main execution thread dies (the end of the program). 在这种情况下,您的竞争条件是线程可以在主执行线程死亡(程序结束)之前被杀死之前打印其输出。 The output from the main thread is not guaranteed to be first, but because it has less overhead from being started, it's likely to be first. 主线程的输出不能保证是第一位的,但是由于它从启动时的开销较小,因此很可能是第一位的。 You can test this by changing the Task.WaitAll to a System.Threading.Thread.Sleep(200) and see what your output becomes as you modify the milliseconds you pass into the Sleep method. 您可以通过将Task.WaitAll更改为System.Threading.Thread.Sleep(200)并查看在修改传递给Sleep方法的毫秒数后输出的内容。

Without waiting, the main thread kills off child threads regardless of what condition they are in. In the case you mentioned, threads B and C had completed between the Console.WriteLine('Hi ABC') and the end of the program. 无需等待,主线程将杀死子线程,无论它们处于什么条件。在您提到的情况下,线程B和C在Console.WriteLine('Hi ABC')和程序结束之间已经完成。 Thread A did not finish, so it got killed before it could output. 线程A没有完成,因此在输出之前就被杀死了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM