是否可以通过使用 Task.Delay 强制新线程来确定任务的并行性?

Is it possible to determine parallelism of tasks by using Task.Delay to force a new thread?

我正在尝试根据任务调度程序做出的决定来确定任务 CAN 运行 并行。有人告诉我这并不能证明情况:

        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var tasks = new List<Task>();
        for (int i = 0; i < 50; i++)
        {
            tasks.Add(Task.Run(async () =>
            {
                await Task.Delay(1000);
            }));
        }

        await Task.WhenAll(tasks);
        stopwatch.Stop();
        // should be 50000 without any parallelism
        var elapsedTime = stopwatch.ElapsedMilliseconds; // on my machine actual result is around 10000

所以我现在对此很困惑。怎么可能最后的结果在执行时间上小于执行每个任务所花费的时间*任务的数量而不能证明某种程度的并行性?

您不应尝试自己控制并行度。

比显式创建和启动线程更好的方法是使用 parallel for:

Parallel.For(0, 50, i => { Thread.Sleep(1000); } );

任务并行机制然后自动确定最佳线程数(基于可用内核数)并在这些线程之间分配任务。

这也减少了创建比并行执行更多线程的开销。

I am trying to determine that Tasks CAN run in parallel depending on decisions made by the task scheduler... How could it be possible that the final result in executing time is less than the time it takes to perform each task * the amount of tasks and not prove some degree of parallelism?

证明并发,可能是异步并发,也可能是并行。在这种情况下,您的代码正在执行异步并发。

请务必注意,任务调度程序仅适用于 运行ning 任务 - 即实际执行代码或被阻止的任务。 运行s await Task.Delay在延迟时间内既不执行代码也不阻塞的线程

So what I mean is can Task.whenall be parallel or only concurrent?

理论上,您可以并行使用 WhenAll。您只需要将代码更改为阻塞而不是异步,它将 运行 并行:

var stopwatch = new Stopwatch();
stopwatch.Start();
var tasks = new List<Task>();
for (int i = 0; i < 50; i++)
{
  tasks.Add(Task.Run(async () =>
  {
    Thread.Sleep(1000);
  }));
}

await Task.WhenAll(tasks);
stopwatch.Stop();
var elapsedTime = stopwatch.ElapsedMilliseconds;

在这种情况下,您的代码是并行的。像这样使用 Task.WhenAll 会起作用,但这是不常见的。通常,使用 Task.WaitAll.

等阻塞方法来使用并行代码