c# - ThreadPoolTaskScheduler internals - Task.WaitAll() 的参数顺序会改变执行顺序吗?
问题描述
我在工作中遇到过类似以下的案例。(为了这个线程的目的,我稍微简化了一点)
这是代码(.net 核心控制台应用程序):
class Program
{
static void Main(string[] args)
{
const int numberOfTasks = 15;
var taskArray = new Task[numberOfTasks];
for (int i = 0; i < numberOfTasks; i++)
{
var temp = i;
taskArray[i] = Task.Run(() => SingleTest(temp));
}
Task.WaitAll(taskArray);
Console.WriteLine("FINISHED!!!");
Console.ReadKey();
}
static void SingleTest(int temp)
{
var signal = new AutoResetEvent(false);
var t1 = Task.Run(() =>
{
Console.WriteLine($"{temp} T1 started");
signal.Set();
Console.WriteLine($"{temp} T1 finished");
});
var t2 = Task.Run(() =>
{
Console.WriteLine($"{temp} T2 started");
signal.WaitOne();
Console.WriteLine($"{temp} T2 finished");
});
Task.WaitAll(t1, t2);
//Task.WaitAll(t2, t1);
Console.WriteLine($"{temp}: Both tasks finished");
}
}
当我使用 8 次或更多循环迭代运行此代码时,在所有 T2 任务启动之前,没有一个 T1 任务启动,这看起来很奇怪。我的问题是为什么会发生这种情况?我本来希望这些任务以完全随机的顺序开始。
这是示例执行的输出开始(8 次迭代):
5 T2 started
7 T2 started
3 T2 started
0 T2 started
4 T2 started
6 T2 started
2 T2 started
1 T2 started
1 T1 started
1 T1 finished
1 T2 finished
1: Both tasks finished
...
当我更改 Task.WaitAll() 调用中的参数顺序时(如注释掉的行),行为完全不同,其中任务以(看似)随机顺序启动(大多数 T1 任务似乎开始早于它们的 T2 等效项,但是在所有 T1 任务完成之前至少启动了一些 T2 任务)
样本输出:
7 T1 started
5 T1 started
5 T1 finished
4 T1 started
4 T1 finished
1 T1 started
1 T1 finished
6 T1 started
6 T1 finished
3 T1 started
3 T1 finished
1 T2 started --For example,this T2 task was started before some of the T1 tasks
0 T1 started
0 T1 finished
2 T1 started
2 T1 finished
4 T2 started
4 T2 finished
3 T2 started
1 T2 finished
7 T1 finished
0 T2 started
0 T2 finished
2 T2 started
6 T2 started
6 T2 finished
3 T2 finished
1: Both tasks finished
所以,我想知道的是,在创造这种行为的幕后发生了什么?
解决方案
推荐阅读
- css - 为什么我在 .row 中的所有元素的高度都不相同?
- c++ - 使用 Media Foundation 源阅读器阅读 3D(左右)视频
- python-3.x - Keras - 基于用户输入的 EarlyStopping
- swagger-ui - 原因:org.springframework.web.servlet.NoHandlerFoundException:没有为 GET /null/swagger-resources/configuration/ui 找到处理程序
- android - 如何控制分辨率屏幕大小
- node.js - Node.js 中的同步请求与 async.retry
- android - 未解决的参考广告视图、广告请求、移动广告
- c - SWIG:结构字段的“out”类型映射需要访问相同结构的另一个字段
- clojure - 进程过滤器中的错误:正则表达式匹配器中的堆栈溢出
- sql - PLS-00103:在预期以下情况之一时遇到符号“IF”:;