zoukankan      html  css  js  c++  java
  • async & await的学习笔记

    异步编程笔记:

    场景:在一个Fun中获取用户的ID,姓名,金额.其中.用户的金额是另一个接口返回的..

    同步编程步骤

    Fun()

    {

      1. 获取用户ID,姓名         =====>假设耗时3秒

      2.调用接口获取用户金额     ======>假设耗时4秒

      3.组装数据,返回结果      ======>假设耗时0.1秒

    }

    此时该Fun()的执行时间是>=7.1秒.

    异步编程步骤

    Fun2()

    {

      1.获取用户ID,姓名          =====>假设耗时3秒

      1-1:同时开启新线程获取用户金额  =====>假设耗时4秒

      2.当1-1返回数据后,组装数据,返回结果.   ===> 在执行Fun2()的第4~5秒时就开始执行了. ,假设耗时0.1秒

    }

    Fun2()的执行时间是>=4.1秒, 

    上面是使用场景以及不同策略给出的理论数据..下面看代码:

    namespace AsyncLearn
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<A> list = new List<A>();
                Stopwatch sw = new Stopwatch();
                sw.Start();
                Console.WriteLine("async get money");//异步线程获取金额
                var blistFun = GetMoney();
                Console.WriteLine("process mainThread");//主线程逻辑设置主数据
                for (int i = 0; i < 10; i++)
                {
                    Thread.Sleep(200);
                    list.Add(new A
                    {
                        id = i + 1,
                        name = "mainThread" + i
                    });
                }
                Console.WriteLine("start set money !!!");//重点看这句打印的先后顺序
                blistFun.Result.ForEach((b) => {
                    var item = list.FirstOrDefault(s => s.id == b.id);
                    if (item != null) { item.money = b.money;Console.WriteLine($"set {item.name}"); }
                });
                sw.Stop();
                Console.WriteLine("stop set money");
    
                Console.WriteLine("Finished " + sw.Elapsed.TotalSeconds);
                Console.ReadKey();
            }
    
            static async Task<List<B>> GetMoney()
            {
                Console.WriteLine("start process money");
                List<B> blist = new List<B>();
                await Task.Run(() =>
                {
                    for (int i = 1; i < 15; i += 2)
                    {
                        Thread.Sleep(100);//修改此处时间,观察带"!!!"的消息
                        blist.Add(new B
                        {
                            id = i,
                            money = i * 3
                        });
                    }
                });
                Console.WriteLine("stop process money !!!");//重点看这句打印的先后顺序
                return blist;
            }
        }
        public class A
        {
            public int id { get; set; }
            public string name { get; set; }
    
            public int money { get; set; }
        }
    
        public class B
        {
            public int id { get; set; }
            public int money { get; set; }
        }
    }

    当GetMoney接口处理速度较快时, Thread.Sleep(100);

    在合并数据之前就已经完成了..

    当我们把GetMoney 接口处理时间加长:Thread.Sleep(800);

     

    此时,带"!!!"的打印位置发生变更了..

    现在,我们来验证下5.64秒的代码变更成单线程执行..

     1 namespace AsyncLearn
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             List<A> list = new List<A>();
     8             Stopwatch sw = new Stopwatch();
     9             sw.Start();
    10             Console.WriteLine("async get money");//异步线程获取金额
    11             var blistFun =GetMoney().Result;
    12             Console.WriteLine("process mainThread");//主线程逻辑设置主数据
    13             for (int i = 0; i < 10; i++)
    14             {
    15                 Thread.Sleep(200);
    16                 list.Add(new A
    17                 {
    18                     id = i + 1,
    19                     name = "mainThread" + i
    20                 });
    21             }
    22             Console.WriteLine("start set money !!!");//重点看这句打印的先后顺序
    23             blistFun.ForEach((b) => {
    24                 var item = list.FirstOrDefault(s => s.id == b.id);
    25                 if (item != null) { item.money = b.money;Console.WriteLine($"set {item.name}"); }
    26             });
    27             sw.Stop();
    28             Console.WriteLine("stop set money");
    29 
    30             Console.WriteLine("Finished " + sw.Elapsed.TotalSeconds);
    31             Console.ReadKey();
    32         }
    33 
    34         static async Task<List<B>> GetMoney()
    35         {
    36             Console.WriteLine("start process money");
    37             List<B> blist = new List<B>();
    38             await Task.Run(() =>
    39             {
    40                 for (int i = 1; i < 15; i += 2)
    41                 {
    42                     Thread.Sleep(800);//修改此处时间,观察带"!!!"的消息
    43                     blist.Add(new B
    44                     {
    45                         id = i,
    46                         money = i * 3
    47                     });
    48                 }
    49             });
    50             Console.WriteLine("stop process money !!!");//重点看这句打印的先后顺序
    51             return blist;
    52         }
    53     }
    54     public class A
    55     {
    56         public int id { get; set; }
    57         public string name { get; set; }
    58 
    59         public int money { get; set; }
    60     }
    61 
    62     public class B
    63     {
    64         public int id { get; set; }
    65         public int money { get; set; }
    66     }
    67 }

    主要变化了第11行和第23行.

    执行结果为:

    关于异步编程的简单用法就先写到这..后期有比较好的场景,和其他用法,再来写点~  欢迎点评~

  • 相关阅读:
    phpcms——列出父目录下的所有子目录问题
    chm格式文档不能阅读问题
    php学习 5 无限级分类
    phpcms——rss问题
    phpcms——评论页面修改
    phpcm后台评论管理修改评论列出条数
    php学习4 函数定义
    网站测试工具
    ASP.NET前台代码绑定后台变量方法总结收藏帖
    在asp.net网站下使用fckeditor 和fcfinder (包括修改fcfinder 来使上传文件按时间来命名和按用户分割文件)
  • 原文地址:https://www.cnblogs.com/Raspberry-zx/p/9988196.html
Copyright © 2011-2022 走看看