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

    https://blog.csdn.net/hurrycxd/article/details/79827958

    书上看到一个Task.Yield例子,Task.Yield方法创建一个立即返回的awaitable。等待一个Yield可以让异步方法在执行后续的部分时返回到调用方法。可以理解为离开当前的消息队列,回到队列末尾,让处理器有时间处理其他任务。
    Yield方法在GUI编程中非常的有用,可以中断大量的工作,让其他任务使用处理器。看下面的代码:

     1         static void Main(string[] args)
     2         {
     3             Task<int> value = FindSeriesSum(100000);
     4             Console.WriteLine("主线其他任务开始");
     5             CountBig(10000);
     6             CountBig(10001);
     7             CountBig(10002);
     8             Thread.Sleep(1000);
     9             CountBig(10003);
    10             Console.WriteLine("Length =" + value.Result);
    11             Console.ReadKey();
    12         }
    13         public static async Task<int> FindSeriesSum(int i1)
    14         {
    15             int sum = 0;
    16             for (int i = 0; i < i1; i++)
    17             {
    18                 sum += i1;
    19                 if (i % 20000 == 0)
    20                 {
    21                     await Task.Yield();
    22                     Console.WriteLine("i % 20000 :i=" + i);
    23                 }
    24             }
    25             WebClient wc = new WebClient();
    26             Console.WriteLine("开始下载任务");
    27             string str = await wc.DownloadStringTaskAsync("https://www.baidu.com");
    28             return str.Length;
    29         }
    30         private static void CountBig(int p)
    31         {
    32             for (int i = 0; i < p; i++)
    33             {
    34                 if (i == p - 1)
    35                     Console.WriteLine("p =" + p);
    36             }
    37         }

    在执行下载任务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不会阻塞线程,线程可以继续处理其它的工作。

     1         static void Main(string[] args)
     2         {
     3             Task<int> value = FindSeriesSum(100000);
     4             Console.WriteLine("主线其他任务开始");
     5             CountBig(10000);
     6             CountBig(10001);
     7             CountBig(10002);
     8             Thread.Sleep(1000);
     9             CountBig(10003);
    10             Console.WriteLine("Length =" + value.Result);
    11             Console.ReadKey();
    12         }
    13         public static async Task<int> FindSeriesSum(int i1)
    14         {
    15             await Task.Delay(1000);
    16             WebClient wc = new WebClient();
    17             Console.WriteLine("开始下载任务");
    18             string str = await wc.DownloadStringTaskAsync("https://www.baidu.com");
    19             return str.Length;
    20         }
    21         private static void CountBig(int p)
    22         {
    23             for (int i = 0; i < p; i++)
    24             {
    25                 if (i == p - 1)
    26                     Console.WriteLine("p =" + p);
    27             }
    28         }

    主线其他任务开始
    p =10000
    p =10001
    p =10002
    开始下载任务
    p =10003
    Length =52728

  • 相关阅读:
    shell语句for循环
    ls命令详解
    计算机相关概念总结(3)
    计算机相关概念总结(2)
    计算机相关概念总结(1)
    devops的概念
    jenkins无法连接gitlab
    Jenkins创建镜像后无法推送到harbor的问题
    Jenkins+gitlab+maven持续集成
    jenkins打完包在哪里
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/10127962.html
Copyright © 2011-2022 走看看