异步编程笔记:
场景:在一个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行.
执行结果为:
关于异步编程的简单用法就先写到这..后期有比较好的场景,和其他用法,再来写点~ 欢迎点评~