我在工作中遇到过以下情况。 (出于这个线程的目的,我对此做了一些简化)
这是代码(.net核心控制台应用程序):
private void UseVars(List<string> vars) {
foreach (string s in vars)
DoSomethingWith(s);
// OR
for (int i = 0; i < vars.Count; i++)
DoSomethingWith(vars[i]);
}
当我使用8次或更多次循环迭代运行此代码时,所有T2任务都未启动之前,没有T1任务启动,这似乎很奇怪。我的问题是为什么会这样?我本来希望任务以完全随机的顺序开始。
这是示例执行(8次迭代)输出的开始:
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");
}
}
当我更改Task.WaitAll()调用中参数的顺序时(如注释行中所示),其行为就大不相同了,其中任务以(看似)随机顺序启动(大多数T1任务)似乎早于其T2等效项开始,但是至少在完成所有T1任务之前启动了一些T2任务)
示例输出:
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
...
那么,我想知道的是,在幕后为了创造这种行为正在发生什么?