zoukankan      html  css  js  c++  java
  • .net中Task.Yield和Task.Delay说明

    书上看到一个Task.Yield例子,Task.Yield方法创建一个立即返回的awaitable。等待一个Yield可以让异步方法在执行后续的部分时返回到调用方法。可以理解为离开当前的消息队列,回到队列末尾,让处理器有时间处理其他任务。

    Yield方法在GUI编程中非常的有用,可以中断大量的工作,让其他任务使用处理器。

    看下面的代码:

    static void Main(string[] args)
    {
        Task<int> value = FindSeriesSum(100000);
        Debug.WriteLine("主线其他任务开始");
        CountBig(10000);
        CountBig(10001);
        CountBig(10002);
        Thread.Sleep(1000);
        CountBig(10003);
        Debug.WriteLine("Length =" + value.Result);
        Console.ReadKey();
    }
    public static async Task<int> FindSeriesSum(int i1)
    {
        int sum = 0;
        for (int i = 0; i < i1; i++)
        {
            sum += i1;
            if (i % 20000 == 0)
            {
                //await Task.Yield();
                Debug.WriteLine("i % 20000 :i=" + i);
            }
        }
        WebClient wc = new WebClient();
        Debug.WriteLine("开始下载任务");
        string str =await wc.DownloadStringTaskAsync("https://github.com/");
        return str.Length;
    }
    private static void CountBig(int p)
    {
        for (int i = 0; i < p; i++)
        {
            if (i == p - 1)
                Debug.WriteLine("p =" + p);
        }
    }

    在执行下载任务await wc.DownloadStringTaskAsync("https://github.com/")前进行了大量的CPU运算,那么线程会等到第一个await的时候才会异步执行CountBig(10000);

    程序运行的结果如下:

    i % 20000 :i=0
    i % 20000 :i=20000
    i % 20000 :i=40000
    i % 20000 :i=60000
    i % 20000 :i=80000
    开始下载任务
    主线其他任务开始
    p =10000
    p =10001
    p =10002
    p =10003
    Length =52728

    我们需要立即返回的awaitable,让程序执行其他的任务,去掉//await Task.Yield();前面的注释符,得到的结果如下:

    i % 20000 :i=0
    主线其他任务开始
    p =10000
    i % 20000 :i=20000
    p =10001
    p =10002
    i % 20000 :i=40000
    i % 20000 :i=60000
    i % 20000 :i=80000
    开始下载任务
    p =10003
    Length =52728

    可以看到现在开始下载任务之前就可以执行其他的任务了。最大条件的利用了资源。

    Task.Delay方法创建一个Task对象,该对象暂停其在线程中的处理。

    与Thread.Sleep()阻塞线程不同的是,Task.Delay不会阻塞线程,线程可以继续处理其它的工作。

            static void Main(string[] args)
            {
                Task<int> value = FindSeriesSum(100000);
                Debug.WriteLine("主线其他任务开始");
                CountBig(10000);
                CountBig(10001);
                CountBig(10002);
                Thread.Sleep(1000);
                CountBig(10003);
                Debug.WriteLine("Length =" + value.Result);
                Console.ReadKey();
            }
            public static async Task<int> FindSeriesSum(int i1)
            {
                await Task.Delay(1000);
                WebClient wc = new WebClient();
                Debug.WriteLine("开始下载任务");
                string str =await wc.DownloadStringTaskAsync("https://github.com/");
                return str.Length;
            }
            private static void CountBig(int p)
            {
                for (int i = 0; i < p; i++)
                {
                    if (i == p - 1)
                        Debug.WriteLine("p =" + p);
                }
            }
    主线其他任务开始
    p =10000
    p =10001
    p =10002
    开始下载任务
    p =10003
    Length =52728
  • 相关阅读:
    CentOS7 安装Redis Cluster集群
    CentOS7 安装Redis 单机版
    CentOS7 配置免密登陆
    深入java虚拟机学习 -- 内存管理机制
    深入java虚拟机学习 -- 类的卸载
    深入java虚拟机学习 -- 类的加载机制(四)
    深入java虚拟机学习 -- 类的加载机制(三)
    深入java虚拟机学习 -- 类的加载机制(续)
    (原创)cocos lua 热更新从零开始(一)最简单demo
    lua 调用参数报错(a userdata value)
  • 原文地址:https://www.cnblogs.com/hueychan/p/10575909.html
Copyright © 2011-2022 走看看