C#中的Task.Delay()和Thread.Sleep()区别(代码案例)
iamitnan · 132浏览 · 发布于2021-06-16 +关注

Task.Delay(),async/await和CancellationTokenSource组合起来使用可以实现可控制的异步延迟。本文通过多种代码案例给大家分析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()比较

代码:

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

相关推荐

PHP实现部分字符隐藏

沙雕mars · 910浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 379浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 488浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 536浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 504浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页