繁体   English   中英

TPL等待好奇心

[英]TPL wait curiosity

我在和TPL一起玩,发现一些很奇怪的东西。 代码等待任务结束,然后进行此虚拟测试,发现在Wait调用之后执行了两个任务。 我丢失了什么,或者这是TPL问题?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Task tareas = null;

            Console.WriteLine("Start process");
            for (int i = 0; i < 4000; i++)
            {
                var n = i.ToString();
                tareas = Task.Factory.StartNew(() =>
                {
                    var random = new Random();
                    Thread.Sleep(random.Next(200, 500));

                    Console.WriteLine("Task completed: " + n);
                });
            }

            tareas.Wait();

            Console.WriteLine("Process end");

            Console.Read();
        }
    }
}

输出:

Start process
Task completed: 4
Task completed: 3

...

End process
Task completed: 3996
Task completed: 3991
Task completed: 3993

好吧, tareas.Wait(); 只等待创建的最后一个任务完成 由于您的任务是在随机的时间内完成的,因此您创建的最后一个任务完成后,某些任务还没有完成是完全正常的。

这是可能发生的情况的示例:

Task 1 created
Task 2 created
Task 3 created
Task 4 created

Task 1 completed
Task 3 completed

Wait for task 4 completion
Task 4 completed

// task 2 executed during more time than other 
// tasks because of the random value the thread waited
Task 2 completed

正如其他人指出的那样,您只在等待一个任务,最后一个任务已排定。

定于默认任务TaskScheduler使用线程池所描述的执行工作项目在这里 使用此调度程序,无法保证订购。 框架将尝试平衡池中每个线程上运行的队列,但是放置最后调度任务的队列可能会(而不是不常见)在所有其他队列之前完成所有任务的运行。

这甚至没有考虑Wait 请查看我链接的文档中标有“任务内联”的部分–如果正在等待任务,则执行等待的线程会说:“好吧,直到该任务完成,我才能做任何事情,让我看看是否可以自己执行它。 在这种情况下,该任务将从线程池队列中完全删除。

taereas将包含对您最后创建的线程的引用,因此treas.Wait()将仅等待最后一个线程完成,因此即使您最后一个线程完成后,其他线程也可能会运行。

好的,仅是为了回答问题, 链接说明了如何等待所有操作完成。

暂无
暂无

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

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