What is going on with Task.Delay().Wait()?

后端 未结 3 2481
天命终不由人
天命终不由人 2021-02-20 09:59

I\'m confused why Task.Delay().Wait() takes 4x more time, then Thread.Sleep()?

E.g. task-00 was running on

3条回答
  •  清歌不尽
    2021-02-20 10:21

    Your problem is that you are mixing asynchronous code with synchronous code without using async and await. Don't use synchronous call .Wait, it's blocking your thread and that's why asynchronous code Task.Delay() won't work properly.

    Asynchronous code often won't work properly when called synchronously because it isn't designed to work that way. You can get lucky and asynchronous code seems to work when running synchronously. But if you are using some external library author of that library can change their code in a way to will break your code. Asynchronous code should be all the way down asynchronous.

    Asynchronous code is usually slower than synchronous one. But benefit is that it runs asynchronously, example if your code is waiting for file to load some other code can run on same CPU Core while that file is loading.

    Your code should look like below, but with async you can't be sure that ManagedThreadId will stay the same. Because thread running your code can change during execution. You should never use ManagedThreadId property or [ThreadStatic] attribute if you using asynchronous code anyway because of that reason.

    Async/Await - Best Practices in Asynchronous Programming

    bool flag = true;
    var sw = Stopwatch.StartNew();
    for (int i = 0; i < 10; i++)
    {
        var cntr = i;
        {
            var start = sw.ElapsedMilliseconds;
            var wait = flag ? 100 : 300;
            flag = !flag;
    
            Task.Run(async () =>
            {
                Console.WriteLine($"task-{cntr.ToString("00")} \t ThrID: {Thread.CurrentThread.ManagedThreadId.ToString("00")},\t Wait={wait}ms, \t START: {start}ms");
                await Task.Delay(wait);
                Console.WriteLine($"task-{cntr.ToString("00")} \t ThrID: {Thread.CurrentThread.ManagedThreadId.ToString("00")},\t Wait={wait}ms, \t END: {sw.ElapsedMilliseconds}ms");
            });
        }
    }
    Console.ReadKey();
    return;
    

提交回复
热议问题