为什么取消Task.Delay会变慢?

Pab*_*ney 2 c# asynchronous

我创建了一个运行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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我在.NET Core 2.1中的结果:

Cancelation done after 9808ms
Run Code Online (Sandbox Code Playgroud)

为什么取消Task.Delay这么慢,有没有办法改进它?

我在.NET 4.7.1中的结果:

Cancelation done after 6200ms
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 5

当我运行这个时,F5我得到了类似的结果.
使用Ctrl+ F5(无调试器)运行它,并在不到50毫秒内取消.

所以你实际上计时1000个execptions搔调调试器.调试器也可能与其他执行点相关.始终在发布模式下运行基准测试,无需调试器.