一、简介
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()比较
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
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()同步
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//该段代码通过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()取消
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
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()的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/wml-it/p/14850246.html