什么时候使用Task.Delay,什么时候使用Thread.Sleep?

本文翻译自:When to use Task.Delay, when to use Thread.Sleep?

Are there good rule(s) for when to use Task.Delay versus Thread.Sleep ? 对于何时使用Task.DelayThread.Sleep是否有好的规则?

  • Specifically, is there a minimum value to provide for one to be effective/efficient over the other? 具体来说,是否存在一个最小值才能使一个方法比另一个方法有效/有效?
  • Lastly, since Task.Delay causes context-switching on a async/await state machine, is there an overhead of using it? 最后,由于Task.Delay导致在异步/等待状态机上进行上下文切换,因此使用它会产生开销吗?

#1楼

参考:https://stackoom.com/question/1MGIn/什么时候使用Task-Delay-什么时候使用Thread-Sleep


#2楼

Use Thread.Sleep when you want to block the current thread. 要阻止当前线程时,请使用Thread.Sleep

Use Task.Delay when you want a logical delay without blocking the current thread. 如果需要逻辑延迟而不阻塞当前线程,请使用Task.Delay

Efficiency should not be a paramount concern with these methods. 对于这些方法,效率不应该是最重要的问题。 Their primary real-world use is as retry timers for I/O operations, which are on the order of seconds rather than milliseconds. 它们在现实世界中的主要用途是作为I / O操作的重试计时器,其数量级为秒而不是毫秒。


#3楼

if the current thread is killed and you use Thread.Sleep and it is executing then you might get a ThreadAbortException . 如果当前线程被杀死,并且您使用Thread.Sleep并且正在执行,则可能会收到ThreadAbortException With Task.Delay you can always provide a cancellation token and gracefully kill it. 使用Task.Delay您始终可以提供取消令牌并优雅地杀死它。 Thats one reason I would choose Task.Delay . 那就是我选择Task.Delay原因Task.Delay see http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx 参见http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx

I also agree efficiency is not paramount in this case. 我也同意在这种情况下效率不是最重要的。


#4楼

The biggest difference between Task.Delay and Thread.Sleep is that Task.Delay is intended to run asynchronously. Task.DelayThread.Sleep之间的最大区别是Task.Delay旨在异步运行。 It does not make sense to use Task.Delay in synchronous code. 在同步代码中使用Task.Delay没有意义。 It is a VERY bad idea to use Thread.Sleep in asynchronous code. 在异步代码中使用Thread.Sleep是一个非常糟糕的主意。

Normally you will call Task.Delay() with the await keyword: 通常,您将使用await关键字调用Task.Delay()

await Task.Delay(5000);

or, if you want to run some code before the delay: 或者,如果您想在延迟之前运行一些代码:

var sw = new Stopwatch();
sw.Start();
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;

Guess what this will print? 猜猜这将打印什么? Running for 0.0070048 seconds. 运行0.0070048秒。 If we move the await delay above the Console.WriteLine instead, it will print Running for 5.0020168 seconds. 如果将await delay移至Console.WriteLine上方,它将显示“运行”为5.0020168秒。

Let's look at the difference with Thread.Sleep : 让我们看看与Thread.Sleep的区别:

class Program
{
    static void Main(string[] args)
    {
        Task delay = asyncTask();
        syncCode();
        delay.Wait();
        Console.ReadLine();
    }

    static async Task asyncTask()
    {
        var sw = new Stopwatch();
        sw.Start();
        Console.WriteLine("async: Starting");
        Task delay = Task.Delay(5000);
        Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        await delay;
        Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        Console.WriteLine("async: Done");
    }

    static void syncCode()
    {
        var sw = new Stopwatch();
        sw.Start();
        Console.WriteLine("sync: Starting");
        Thread.Sleep(5000);
        Console.WriteLine("sync: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        Console.WriteLine("sync: Done");
    }
}

Try to predict what this will print... 尝试预测将要打印的内容...

async: Starting 异步:开始
async: Running for 0.0070048 seconds 异步:运行0.0070048秒
sync: Starting 同步:开始
async: Running for 5.0119008 seconds 异步:运行5.0119008秒
async: Done 异步:完成
sync: Running for 5.0020168 seconds 同步:运行5.0020168秒
sync: Done 同步:完成

Also, it is interesting to notice that Thread.Sleep is far more accurate, ms accuracy is not really a problem, while Task.Delay can take 15-30ms minimal. 另外,有趣的是, Thread.Sleep准确性要高得多,ms的准确性并不是真正的问题,而Task.Delay占用时间最少为15-30ms。 The overhead on both functions is minimal compared to the ms accuracy they have (use Stopwatch Class if you need something more accurate). 与它们具有的ms精度相比,这两个函数的开销是最小的(如果您需要更精确的信息,请使用Stopwatch Class)。 Thread.Sleep still ties up your Thread, Task.Delay release it to do other work while you wait. Thread.Sleep仍然占用您的线程, Task.Delay释放它以便在您等待时进行其他工作。


#5楼

I want to add something. 我要添加一些东西。 Actually, Task.Delay is a timer based wait mechanism. 实际上, Task.Delay是基于计时器的等待机制。 If you look at the source you would find a reference to a Timer class which is responsible for the delay. 如果您查看源代码 ,则会发现对造成延迟的Timer类的引用。 On the other hand Thread.Sleep actually makes current thread to sleep, that way you are just blocking and wasting one thread. 另一方面, Thread.Sleep实际上使当前线程进入睡眠状态,这样您就只能阻塞并浪费一个线程。 In async programming model you should always use Task.Delay() if you want something(continuation) happen after some delay. 在异步编程模型中,如果希望延迟后发生某些事情(继续),则应始终使用Task.Delay()

猜你喜欢

转载自blog.csdn.net/p15097962069/article/details/107659301