[英]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.