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()的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#利用System.Threading.Thread.Sleep即时输出信息的详解

    有个网站需要生成静态页.据以往经验,凡比较烂的空间,短时间内运行耗能大的运算,都会出现"service unavailable",以致网页无法正常打开.生成静态页,需要在短时间内读取大量的数据并保存为html页,好一些的空间运行起来没问题,就怕那些垃圾空间--生成的时候,需要即时输出信息通知客户. 根据经验思考后,有两种方法可行:1.每次只执行生成一个html页,然后输出信息给客户看,如"已生成首页,正在生成新闻页,请稍候..",然后在输出的代码里放置上js代码,j

  • 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()最大的区别

  • PHP swoole中使用task进程异步的处理耗时任务应用案例分析

    本文实例讲述了PHP swoole中使用task进程异步的处理耗时任务.分享给大家供大家参考,具体如下: 我们知道,swoole中有两大进程,分别是 master 主进程和 manager 管理进程. 其中 master 主进程中会有一个主 reactor 线程和多个 reactor 线程,主要的作用就是用来维护TCP连接,处理网络IO,收发数据. 而 manager 管理进程,作用则是 fork 和管理 worker 和 task 进程. worker 进程的作用是接收 reactor 线程传

  • c#中task与thread的区别及使用讲解

    目录 一.什么是thread 二.什么是task 三.创建一个task任务有两种模式 1.使用factory创建会直接执行 2.我们来看看task的生命周期 3.下面演示几个控制task的方法 4.task的回调执行 5.task的取消 6.task的嵌套 6.task死锁的问题 7.对Spinlock的使用 一.什么是thread 当我们提及多线程的时候会想到thread和threadpool,这都是异步操作,threadpool其实就是thread的集合,具有很多优势,不过在任务多的时候全局

  • C#多线程学习之Thread、ThreadPool、Task、Parallel四者区别

    目录 Thread ThreadPool Task Parallel Task专讲 线程(英语:thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.进程是资源分配的基本单位.所有与该进程有关的资源,都被记录在进程控制块PCB中.以表示该进程拥有这些资源或正在使用它们.本文以一些简单的小例子,简述多线程的发展历程[Thread,ThreadPool,Task

  • java 中Spring task定时任务的深入理解

    java 中Spring task定时任务的深入理解 在工作中有用到spring task作为定时任务的处理,spring通过接口TaskExecutor和TaskScheduler这两个接口的方式为异步定时任务提供了一种抽象.这就意味着spring容许你使用其他的定时任务框架,当然spring自身也提供了一种定时任务的实现:spring task.spring task支持线程池,可以高效处理许多不同的定时任务.同时,spring还支持使用Java自带的Timer定时器和Quartz定时框架.

  • 浅析Java中Runnable和Thread的区别

    线程的起动并不是简单的调用了你的RUN方法,而是由一个线程调度器来分别调用你的所有线程的RUN方法, 我们普通的RUN方法如果没有执行完是不会返回的,也就是会一直执行下去,这样RUN方法下面的方法就不可能会执行了,可是线程里的RUN方法却不一样,它只有一定的CPU时间,执行过后就给别的线程了,这样反复的把CPU的时间切来切去,因为切换的速度很快,所以我们就感觉是很多线程在同时运行一样. 你简单的调用run方法是没有这样效果的,所以你必须调用Thread类的start方法来启动你的线程.所以你启动

  • C#中的Task.WhenAll和Task.WhenAny方法介绍

    一.简介 Task.WhenAll().Task.WhenAny()这两个与Task.WaitALL().Task.WaitAny()是有区别的,When是异步的,Wait是同步的.Task.WhenAll():所有提供的任务已完成时,创建将完成的任务.Task.WhenAny():任何提供的任务已完成时,创建将完成的任务. 二.代码案例 Task.WhenAll 代码: class Program { public class DownLoadTest { Stopwatch watch =

  • C#中Backgroundworker与Thread的区别

    目录 1.Backgroundworker 2.Thread 3.总结 最近项目要用到,窗体Form程序要在后台开启几个子线程,负责和其他端进行通信,异步读写,并且来更改UI.在网上查了有Backgroundworker与Thread两种方法. 1.Backgroundworker BackgroundWorker是微软的在.net Framwork中添加的一个组件,主要对线程的访问提供了一种安全的方式.简单的说就是对Thread的一次封装. 首先介绍一下BackgroundWorker的相关属

  • C#中的Task.WaitAll和Task.WaitAny方法介绍

    一.简介 Task.WaitAll:等待所有提供的 Task 对象完成执行过程. Task.WaitAny:等待提供的任一 Task 对象完成执行过程. 二.代码案例 Task.WaitAll 代码: class Program { public class DownLoadTest { Stopwatch watch = new Stopwatch(); public DownLoadTest() { watch.Start(); } public async Task DoRunTaskAs

  • java 线程中start方法与run方法的区别详细介绍

    线程中start方法与run方法的区别 在线程中,如果start方法依次调用run方法,为什么我们会选择去调用start方法?或者在java线程中调用start方法与run方法的区别在哪里?  这两个问题是两个非常流行的初学者级别的多线程面试问题.当一个Java程序员开始学习线程的时候,他们首先会学着去继承Thread类,重载run方法或者实现Runnable接口,实现run方法,然后调用Thread实例的start方法.但是当他拥有一些经验之后,他通过查看API文档或者其他途径会发现start

随机推荐