Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么取消任务。延迟慢?_C#_Asynchronous - Fatal编程技术网

C# 为什么取消任务。延迟慢?

C# 为什么取消任务。延迟慢?,c#,asynchronous,C#,Asynchronous,我创建了一个测试程序,可以运行1000个任务,这些任务执行Task.Delay,随机延迟在20秒到30秒之间。 取消此操作似乎需要10秒左右 这是我的测试程序: class Program { static async Task MainAsync() { CancellationTokenSource tokenSource = new CancellationTokenSource(); List<Task> allTask =

我创建了一个测试程序,可以运行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 4.7.1的结果:

Cancelation done after 6200ms

不要重复问题的代码。按原样使用,我得到:

Started
1000ms elapsed. Cancelation request start
Cancelation done after 38 ms
End
无重新编程,代码已清除:

static async Task SafeDelay(int delay, CancellationToken token)
{
    try
    {
        await Task.Delay(delay, token);
    }
    catch (TaskCanceledException)
    {
    }
}


private static async Task Main()
{
    //Set 1000 ms timeout
    var tokenSource = new CancellationTokenSource(1000);
    var stopwatch = Stopwatch.StartNew();

    var allTask = new List<Task>();
    Random r = new Random(9); 


    for (var i = 0; i < 1000; i++)
    {
        var randomDelay = r.Next(20000, 30000);
        allTask.Add(SafeDelay(randomDelay, tokenSource.Token));
    }
    Console.WriteLine($"All {allTask.Count} tasks running after {stopwatch.ElapsedMilliseconds} ms");

    await Task.WhenAll(allTask);
    stopwatch.Stop();

    Console.WriteLine($"Cancelation done after {stopwatch.ElapsedMilliseconds} ms");
}
CancellationTokenSource有一个1000毫秒的超时。

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


因此,实际上您正在对1000个执行进行计时,以使调试器感到高兴。调试器可能还会与其他执行点交互。始终在发布模式下运行基准测试,不带调试器

@CamiloTerevinto在等待任务之前未请求取消。whalll(allTask)@PanagiotisKanavos:我将其替换为Task.Run(mainsync.GetAwaiter().GetResult();但我得到了同样的结果result@PabloHoney对于初学者,删除对
ConfigureAwai()
的所有调用。控制台应用程序没有同步上下文。也删除
GetAwaiter().GetResult()
。在这种情况下,它只做
.Wait()
。可能还会删除
Task.Run()
,因为
mainsync
应该是异步的already@PanagiotisKanavos:我删除了所有ConfigureWait(false),但仍获得10185ms@PabloHoney这段代码中有很多不寻常的代码。等待,继续,
配置等待
。按照SafeDelay的编写方式,您实际上正在计算抛出1000个异常所需的时间,我也以10毫秒的速度运行它。但是我找不到你的代码和我的代码之间有任何根本的区别。@PabloHoney你是如何运行它的?至于清理,当面临复杂问题或意外行为时,你必须清除任何不需要的东西。否则,您无法确定是否正在测量测试线束或代码。我运行VStudio中的所有代码,点击播放按钮(F5)@pablohone调试器捕获并分析所有异常,并在代码中启用许多诊断挂钩。调试时不能对任何代码进行基准测试。@PabloHoney-这不是关于代码的问题,而是关于调试器的问题。这可能会使线程暂停,等等。这是一个更复杂的问题。你的原始密码很好,这才是真正的区别。泰
static async Task SafeDelay(int delay, CancellationToken token)
{
    try
    {
        await Task.Delay(delay, token);
    }
    catch (TaskCanceledException)
    {
    }
}


private static async Task Main()
{
    //Set 1000 ms timeout
    var tokenSource = new CancellationTokenSource(1000);
    var stopwatch = Stopwatch.StartNew();

    var allTask = new List<Task>();
    Random r = new Random(9); 


    for (var i = 0; i < 1000; i++)
    {
        var randomDelay = r.Next(20000, 30000);
        allTask.Add(SafeDelay(randomDelay, tokenSource.Token));
    }
    Console.WriteLine($"All {allTask.Count} tasks running after {stopwatch.ElapsedMilliseconds} ms");

    await Task.WhenAll(allTask);
    stopwatch.Stop();

    Console.WriteLine($"Cancelation done after {stopwatch.ElapsedMilliseconds} ms");
}
All 1000 tasks running after 8 ms
Cancelation done after 1044 ms