c# - 为什么取消 Task.Delay 很慢?
问题描述
我创建了一个运行 1000 个任务的测试程序,这些任务Task.Delay
以 20 秒到 30 秒之间的随机延迟执行。取消此操作似乎需要大约 10 秒..
这是我的测试程序:
class Program
{
static async Task MainAsync()
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
List<Task> allTask = new List<Task>();
Random r = new Random(9);
async Task SafeDelay(int delay, CancellationToken token)
{
try
{
await Task.Delay(delay, token);
}
catch (TaskCanceledException)
{
}
}
for (int i = 0; i < 1000; i++)
{
var randomDelay = r.Next(20000, 30000);
allTask.Add(SafeDelay(randomDelay, tokenSource.Token));
;
}
Stopwatch stopwatch = new Stopwatch();
var cancelTask = Task.Delay(1000).ContinueWith(t =>
{
Console.Out.WriteLine("1000ms elapsed. Cancelation request start");;
stopwatch.Start();
tokenSource.Cancel();
});
await Task.WhenAll(allTask);
await cancelTask;
stopwatch.Stop();
Console.WriteLine($"Cancelation done after {stopwatch.ElapsedMilliseconds} ms");
}
static void Main(string[] args)
{
Console.WriteLine("Started");
Task.Run(MainAsync).GetAwaiter().GetResult();
Console.WriteLine("End");
Console.ReadLine();
}
}
我使用 .NET Core 2.1 的结果:
Cancelation done after 9808ms
为什么取消 Task.Delay 这么慢,有没有办法改进它?
我使用 .NET 4.7.1 的结果:
Cancelation done after 6200ms
解决方案
当我运行它时,F5我得到了类似的结果。使用+ (无调试器)
运行它,它会在 50 毫秒内取消。CtrlF5
因此,您实际上是在为调试器计时 1000 次执行。调试器也可能干扰其他执行点。始终在发布模式下运行基准测试,不带调试器。
推荐阅读
- java - 在java中合并两个相同类型的对象列表
- javafx - 加载文档时 FXMLLoader 究竟做了什么?
- core-data - CoreData:过滤结果比较实体的相同属性
- python - numpy - 用分数填充的矩阵/数组的逆 - 错误
- python - 根据字典替换数据框列中的值不起作用
- python - Python异步函数中断时如何实现最终清理?
- visual-studio-code - 如何从 VSCode 扩展中恢复意外删除的键盘快捷键?
- javascript - 在 foreach 循环中将类添加到具有 ID 的每个元素
- selenium-webdriver - Selenium 测试在 Jenkins 中失败,但不是在本地,因为焦点没有被触发
- r - 使用 R 中的循环创建 50 多个国家/地区的地块