C#中的Task.Delay()和Thread.Sleep()区别(代码案例)
作者:農碼一生
一、简介
1.Thread.Sleep()是同步延迟,Task.Delay()是异步延迟。
2.Thread.Sleep()会阻塞线程,Task.Delay()不会。
3.Thread.Sleep()不能取消,Task.Delay()可以。
4.Task.Delay()实质创建一个运行给定时间的任务,Thread.Sleep()使当前线程休眠给定时间。
5.反编译Task.Delay(),基本上讲它就是个包裹在任务中的定时器。
6.Task.Delay()和Thread.Sleep()最大的区别是Task.Delay()旨在异步运行,在同步代码中使用Task.Delay()是没有意义的;在异步代码中使用Thread.Sleep()是一个非常糟糕的主意。通常使用await关键字调用Task.Delay()。
二、代码案例
案例一:Thread.Sleep()和Task.Delay()比较
代码:
static void Main(string[] args) { //阻塞,出现CPU等待... Task.Factory.StartNew(delegate { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ****** Start Sleep()******"); for (int i = 1; i <=10; i++) { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "******Sleep******==>" + i); Thread.Sleep(1000);//同步延迟,阻塞一秒 } Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ******End Sleep()******"); Console.WriteLine(); }); //不阻塞 Task.Factory.StartNew(() => { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======StartDelay()======"); for (int i =1; i <=10; i++) { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======Delay====== ==>" + i); Task.Delay(1000);//异步延迟 } Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======End Delay()======"); Console.WriteLine(); }); Console.ReadLine(); Console.ReadKey(); }
结果:
通过运行结果截图对比看出,Thread.Sleep()是同步延迟,Task.Delay()是异步延迟。
案例二:通过async/await实现Task.Delay()同步
代码:
//该段代码通过async/awatit实现“同步”Delay static void Main(string[] args) { Task.Factory.StartNew(async () => { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======Start Delay()======"); for (int i = 1; i <=10; i++) { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======Delay======" + i); await Task.Delay(1000); } Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======End Delay()======"); }); Console.ReadKey(); }
结果:
运行结果可以看出,通过async/await实现了Task.Delay()同步
案例三:Task.Delay()取消
代码:
class Program { #region CancellationTokenSource cts = new CancellationTokenSource(); void PutThreadSleep() { Thread.Sleep(5000); } async Task PutTaskDelay() { try { await Task.Delay(5000, cts.Token);//需要.net4.5的支持 } catch (TaskCanceledException ex) { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff ==>") + ex.ToString()); } } private void ThreadSleep() { PutThreadSleep(); Console.WriteLine("Sleep : I am back"); } private async void TaskDelay() { await PutTaskDelay(); Console.WriteLine("Delay : I am back"); } private void CancelTaskDelay() { cts.Cancel(); } #endregion static void Main(string[] args) { #region Program p = new Program(); //不可取消 p.ThreadSleep(); //可取消 p.TaskDelay(); p.CancelTaskDelay(); #endregion Console.ReadKey(); } }
结果:
Task.Delay()取消,抛出异常信息。
三、总结
Task.Delay(),async/await和CancellationTokenSource组合起来使用可以实现可控制的异步延迟。
以上就是C#中的Task.Delay()和Thread.Sleep()区别(代码案例)的详细内容,更多关于C# Task.Delay()和Thread.Sleep()的资料请关注脚本之家其它相关文章!