zoukankan      html  css  js  c++  java
  • C#中的Task.Delay()和Thread.Sleep()区别

    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组合起来使用可以实现可控制的异步延迟。


    技术的发展日新月异,随着时间推移,无法保证本博客所有内容的正确性。如有误导,请大家见谅,欢迎评论区指正!
    我创建了一个.NET开发交流群,用于分享学习心得和讨论相关技术难题。欢迎有兴趣的小伙伴扫码入群,相互学习!

  • 相关阅读:
    JAVA-throw new IOException报错unhandled exception:java.lang.Exception 2021年6月7日
    GIt保持远程 源仓库与Fork仓库同步--2017年6月13日
    Python的getattr()-2017年6月7日
    JavaScript学习-2017年5月18日
    Writing your first Django app--2017年5月9日
    M4-AC6 Oh,Trojan Again--2017年5月9日
    吴军硅谷来信
    【1】Prologue--A Game of Thrones--2017年4月8日
    M4-PC9 Read 10,000 Books,Travel 10,000 Miles--2017年5月8日
    资源分配图RAG的化简
  • 原文地址:https://www.cnblogs.com/wml-it/p/14850246.html
Copyright © 2011-2022 走看看