c# - 是否可以通过使用 Task.Delay 强制一个新线程来确定任务的并行性?
问题描述
我试图确定任务可以根据任务调度程序做出的决定并行运行。我被告知这并不能证明这一点:
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
所以我现在对此很困惑。执行时间的最终结果怎么可能小于执行每个任务所需的时间 * 任务数量而不证明某种程度的并行性?
解决方案
我正在尝试根据任务调度程序做出的决定确定任务可以并行运行......执行时间的最终结果怎么可能少于执行每个任务所需的时间 * 任务的数量而不是证明某种程度的并行性?
它证明了并发,可能是异步并发,也可能是并行。在这种情况下,您的代码正在执行异步并发。
需要注意的是,任务调度程序仅适用于正在运行的任务——即实际执行代码或被阻塞的任务。运行的线程await Task.Delay
在延迟时间内既不执行代码也不阻塞。
所以我的意思是 Task.whenall 可以并行还是仅并发?
您可以 - 理论上 -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
.
推荐阅读
- html - 使用 rvest 从 html 站点抓取,但返回结果“类别(空)”
- python - Discord.py 添加角色不超过 1 个单词的角色
- arrays - 在 2d 数组 python 3.x 中组合元素
- python - 用 Pandas 编码
- swift - 无法打开阿拉伯语文本文件
- jquery - InertiaJS 与 VueJS 与 jQuery 冲突
- flutter - 如何在flutter in_app_purchase中获取订阅状态?
- java - 纯 Java 中的 WebSocket
- java - Android Studio onKeyDown、onKeyUp 按键检测问题
- flutter - 无法在 ExpansionPanelList 中展开标题