Task.Delay()、Thread.Sleep()
- Thread.Sleep()是同步延迟,Task.Delay()是异步延迟。
- Thread.Sleep()会阻塞线程,Task.Delay()不会。
- Thread.Sleep()不能取消,Task.Delay()可以。
- Task.Delay()实质创建一个运行给定时间的任务,延时完成后的线程可能不同;Thread.Sleep()使当前线程休眠给定时间,把CPU分片时间让出去,实际上还占有线程资源。
- 反编译Task.Delay(),基本上看它就是个包裹在任务中的定时器 System.Threading.Timer。
- Task.Delay()和Thread.Sleep()最大的区别是Task.Delay()旨在异步运行,在同步代码中使用Task.Delay()是没有意义的;在异步代码中使用Thread.Sleep()是一个非常糟糕的主意。通常使用await关键字调用Task.Delay()。
我的理解:Task.Delay(),async/await和CancellationTokenSource组合起来使用可以实现可控制的异步延迟。
sleep(0)
强制当前线程放弃剩余的CPU时间片(纳秒级),根据优先级调度线程。如果没有更高优先级的线程,会继续运行当前线程。
效果类似于 Thread.Yield()。
sleep(1)
当前线程阻塞1ms。线程调度级别的等待。
while(true) + sleep
一般常用于 循环操作,为防止阻塞,会放在一个单独的线程里运行,造成资源浪费。
可以用System.Timers.Timer替代。
delay(0)
会直接返回Task.CompletedTask,即 Task.Delay(0) 后面的代码会立刻执行。
delay(1)
启动定时器,时间抵达(1ms)后执行回调函数。
由于计时器耗时不可控(OS时钟中断间隔大约15ms),实际等待时间可能接近15ms。
Task.Yield
让一个异步方法立刻返回,让后面其他代码的调用进入下一个异步上下文。
如果此异步方法没有被 await 异步等待,那方法后面其他代码 将在没有异步等待的方法(await所在的方法)之后执行。