在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
概述一天之计在于晨,每天的早餐也是必不可少,但是很多人为了节约时间,都是简单的吃点凑合一下或干脆不吃早餐,这对于个人身体和工作效率来说,无疑是不合理的,那么要如何做一顿早餐呢?如何能节约做早餐的时间呢?本文以一个简单的小例子,简述如何做一顿早餐及如何优化做早餐的时间。仅供学习分享使用,如有不足之处,还请指正。 正常情况下,做早餐可以分为以下几个步骤:
同步方式做早餐根据以上步骤进行编程,做一份早餐需要编写程序如下: 1 /// <summary> 2 /// 同步做早餐 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnBreakfast_Click(object sender, EventArgs e) 7 { 8 this.txtInfo.Clear(); 9 Stopwatch watch = Stopwatch.StartNew(); 10 watch.Start(); 11 //1. 倒一杯咖啡。 12 string cup = PourCoffee(); 13 PrintInfo("咖啡冲好了"); 14 //2. 加热平底锅,然后煎两个鸡蛋。 15 string eggs = FryEggs(2); 16 PrintInfo("鸡蛋煎好了"); 17 //3. 煎三片培根。 18 string bacon = FryBacon(3); 19 PrintInfo("培根煎好了"); 20 //4. 烤两片面包。 21 string toast = ToastBread(2); 22 //5. 在烤面包上加黄油和果酱。 23 ApplyButter(toast); 24 ApplyJam(toast); 25 PrintInfo("面包烤好了"); 26 //6. 倒一杯橙汁。 27 string oj = PourOJ(); 28 PrintInfo("橙汁倒好了"); 29 PrintInfo("早餐准备完毕!"); 30 watch.Stop(); 31 TimeSpan time = watch.Elapsed; 32 PrintInfo(string.Format("总运行时间为:{0}秒", time.TotalSeconds.ToString("0.00"))); 33 } 34 35 /// <summary> 36 /// 倒一杯咖啡 37 /// </summary> 38 /// <returns></returns> 39 private string PourCoffee() 40 { 41 PrintInfo("正在冲咖啡..."); 42 return "咖啡"; 43 } 44 45 /// <summary> 46 /// 抹果酱 47 /// </summary> 48 /// <param name="toast"></param> 49 private void ApplyJam(string toast) => 50 PrintInfo("往面包抹果酱"); 51 52 /// <summary> 53 /// 抹黄油 54 /// </summary> 55 /// <param name="toast"></param> 56 private void ApplyButter(string toast) => 57 PrintInfo("往面包抹黄油"); 58 59 /// <summary> 60 /// 烤面包 61 /// </summary> 62 /// <param name="slices"></param> 63 /// <returns></returns> 64 private string ToastBread(int slices) 65 { 66 for (int slice = 0; slice < slices; slice++) 67 { 68 PrintInfo("往烤箱里面放面包"); 69 } 70 PrintInfo("开始烤..."); 71 Task.Delay(3000).Wait(); 72 PrintInfo("从烤箱取出面包"); 73 74 return "烤面包"; 75 } 76 77 /// <summary> 78 /// 煎培根 79 /// </summary> 80 /// <param name="slices"></param> 81 /// <returns></returns> 82 private string FryBacon(int slices) 83 { 84 PrintInfo($"放 {slices} 片培根在平底锅"); 85 PrintInfo("煎第一片培根..."); 86 Task.Delay(3000).Wait(); 87 for (int slice = 0; slice < slices; slice++) 88 { 89 PrintInfo("翻转培根"); 90 } 91 PrintInfo("煎第二片培根..."); 92 Task.Delay(3000).Wait(); 93 PrintInfo("把培根放盘子里"); 94 95 return "煎培根"; 96 } 97 98 /// <summary> 99 /// 煎鸡蛋 100 /// </summary> 101 /// <param name="howMany"></param> 102 /// <returns></returns> 103 private string FryEggs(int howMany) 104 { 105 PrintInfo("加热平底锅..."); 106 Task.Delay(3000).Wait(); 107 PrintInfo($"磕开 {howMany} 个鸡蛋"); 108 PrintInfo("煎鸡蛋 ..."); 109 Task.Delay(3000).Wait(); 110 PrintInfo("鸡蛋放盘子里"); 111 112 return "煎鸡蛋"; 113 } 114 115 /// <summary> 116 /// 倒橙汁 117 /// </summary> 118 /// <returns></returns> 119 private string PourOJ() 120 { 121 PrintInfo("倒一杯橙汁"); 122 return "橙汁"; 123 } 同步做早餐示例通过运行示例,发现采用同步方式进行编程,做一份早餐,共计15秒钟,且在此15秒钟时间内,程序处于【卡住】状态,无法进行其他操作。如下所示: 同步做早餐示意图同步方式做早餐,就是一个做完,再进行下一个,顺序执行,如下所示: 同步方式为何会【卡住】?因为在程序进程中,会有一个主线程,用于响应用户的操作,同步方式下,做早餐的和前端页面同在主线程中,所以当开始做早餐时,就不能响应其他的操作了。这就是【两耳不闻窗外事,一心只读圣贤书】的境界。但如果让用户长时间处于等待状态,会让用户体验很不友好。比如,刘玄德三顾茅庐,大雪纷飞之下,诸葛亮在草庐中午睡,刘关张在大雪中静等。试问有几人会有玄德的耐心,何况程序也不是诸葛亮,用户也没有玄德的耐心! 异步方式做早餐上述代码演示了不正确的实践:构造同步代码来执行异步操作。 顾名思义,此代码将阻止执行这段代码的线程执行任何其他操作。 在任何任务进行过程中,此代码也不会被中断。 就如同你将面包放进烤面包机后盯着此烤面包机一样。 你会无视任何跟你说话的人,直到面包弹出。如何做才能避免线程阻塞呢?答案就是异步。 首先更新代码,对于耗时的程序,采用异步方式做早餐,如下所示: 1 private async void btnBreakfastAsync_Click(object sender, EventArgs e) 2 { 3 this.txtInfo.Clear(); 4 Stopwatch watch = Stopwatch.StartNew(); 5 watch.Start(); 6 //1. 倒一杯咖啡。 7 string cup = PourCoffee(); 8 PrintInfo("咖啡冲好了"); 9 //2. 加热平底锅,然后煎两个鸡蛋。 10 //Task<string> eggs = FryEggsAsync(2); 11 string eggs =await FryEggsAsync(2); 12 PrintInfo("鸡蛋煎好了"); 13 //3. 煎三片培根。 14 string bacon =await FryBaconAsync(3); 15 PrintInfo("培根煎好了"); 16 //4. 烤两片面包。 17 string toast =await ToastBreadAsync(2); 18 //5. 在烤面包上加黄油和果酱。 19 ApplyButter(toast); 20 ApplyJam(toast); 21 PrintInfo("面包烤好了"); 22 //6. 倒一杯橙汁。 23 string oj = PourOJ(); 24 PrintInfo("橙汁倒好了"); 25 PrintInfo("早餐准备完毕!"); 26 watch.Stop(); 27 TimeSpan time = watch.Elapsed; 28 PrintInfo(string.Format("总运行时间为:{0}秒", time.TotalSeconds.ToString("0.00"))); 29 } 30 31 /// <summary> 32 /// 异步烤面包 33 /// </summary> 34 /// <param name="slices"></param> 35 /// <returns></returns> 36 private async Task<string> ToastBreadAsync(int slices) 37 { 38 for (int slice = 0; slice < slices; slice++) 39 { 40 PrintInfo("往烤箱里面放面包"); 41 } 42 PrintInfo("开始烤..."); 43 await Task.Delay(3000); 44 PrintInfo("从烤箱取出面包"); 45 46 return "烤面包"; 47 } 48 49 /// <summary> 50 /// 异步煎培根 51 /// </summary> 52 /// <param name="slices"></param> 53 /// <returns></returns> 54 private async Task<string> FryBaconAsync(int slices) 55 { 56 PrintInfo($"放 {slices} 片培根在平底锅"); 57 PrintInfo("煎第一片培根..."); 58 await Task.Delay(3000); 59 for (int slice = 0; slice < slices; slice++) 60 { 61 PrintInfo("翻转培根"); 62 } 63 PrintInfo("煎第二片培根..."); 64 await Task.Delay(3000); 65 PrintInfo("把培根放盘子里"); 66 67 return "煎培根"; 68 } 69 70 /// <summary> 71 /// 异步煎鸡蛋 72 /// </summary> 73 /// <param name="howMany"></param> 74 /// <returns></returns> 75 private async Task<string> FryEggsAsync(int howMany) 76 { 77 PrintInfo("加热平底锅..."); 78 await Task.Delay(3000); 79 PrintInfo($"磕开 {howMany} 个鸡蛋"); 80 PrintInfo("煎鸡蛋 ..."); 81 await Task.Delay(3000); 82 PrintInfo("鸡蛋放盘子里"); 83 84 return "煎鸡蛋"; 85 } 注意:通过测试发现,异步方式和同步方式的执行时间一致,所以采用异步方式并不会缩短时间,但是程序已不再阻塞,可以同时响应用户的其他请求。 优化异步做早餐通过上述异步方式,虽然优化了程序,不再阻塞,但是时间并没有缩短,那么要如何优化程序来缩短时间,以便早早的吃上可口的早餐呢?答案就是在开始一个任务后,在等待任务完成时,可以继续进行准备其他的任务。 你也几乎将在同一时间完成所有工作。 你将吃到一顿热气腾腾的早餐。通过合并任务和调整任务的顺序,将大大节约任务的完成时间,如下所示: 1 /// <summary> 2 /// 优化异步做早餐 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private async void btnBreakfast2_Click(object sender, EventArgs e) 7 { 8 this.txtInfo.Clear(); 9 Stopwatch watch = Stopwatch.StartNew(); 10 watch.Start(); 11 //1. 倒一杯咖啡。 12 string cup = PourCoffee(); 13 PrintInfo("咖啡冲好了"); 14 //2. 加热平底锅,然后煎两个鸡蛋。 15 Task<string> eggsTask = FryEggsAsync(2); 16 //3. 煎三片培根。 17 Task<string> baconTask = FryBaconAsync(3); 18 //4.5合起来 烤面包,抹果酱,黄油 19 Task<string> toastTask = MakeToastWithButterAndJamAsync(2); 20 21 string eggs = await eggsTask; 22 PrintInfo("鸡蛋煎好了"); 23 24 string bacon = await baconTask; 25 PrintInfo("培根煎好了"); 26 27 string toast = await toastTask; 28 PrintInfo("面包烤好了"); 29 //6. 倒一杯橙汁。 30 string oj = PourOJ(); 31 PrintInfo("橙汁倒好了"); 32 PrintInfo("早餐准备完毕!"); 33 watch.Stop(); 34 TimeSpan time = watch.Elapsed; 35 PrintInfo(string.Format("总运行时间为:{0}秒", time.TotalSeconds.ToString("0.00"))); 36 } 37 38 /// <summary> 39 /// 组合任务 40 /// </summary> 41 /// <param name="number"></param> 42 /// <returns></returns> 43 private async Task<string> MakeToastWithButterAndJamAsync(int number) 44 { 45 var toast = await ToastBreadAsync(number); 46 ApplyButter(toast); 47 ApplyJam(toast); 48 return toast; 49 } 在本例中,合并了【烤面包+抹果酱+抹黄油】为一个任务,这样是烤面包的同时,可以煎鸡蛋,煎培根,三项耗时任务同时执行。在三个任务都完成是,早餐也就做好了,示例如下所示: 通过以上优化示例发现,通过合并任务和调整顺序,做一份早餐,需要6.06秒。 优化异步早餐示意图优化后的异步做早餐,由于一些任务并发运行,因此节约了时间。示意图如下所示: 异步异常上述示例假定所有的任务都可以正常完成,那么如果某一个任务执行过程中发生了异常,要如何捕获呢?答案是:当任务无法成功完成时,它们将引发异常。 当启动的任务为 例如当烤面包的时候,烤箱突然着火了,如何处理异常呢?代码如下所示: 1 private async void btnBreakfastAsync3_Click(object sender, EventArgs e) 2 { 3 try 4 { 5 this.txtInfo.Clear(); 6 Stopwatch watch = Stopwatch.StartNew(); 7 watch.Start(); 8 //1. 倒一杯咖啡。 9 string cup = PourCoffee(); 10 PrintInfo("咖啡冲好了"); 11 //2. 加热平底锅,然后煎两个鸡蛋。 12 Task<string> eggsTask = FryEggsAsync(2); 13 //3. 煎三片培根。 14 Task<string> baconTask = FryBaconAsync(3); 15 //4.5合起来 烤面包,抹果酱,黄油 16 Task<string> toastTask = MakeToastWithButterAndJamAsyncEx(2); 17 18 string eggs = await eggsTask; 19 PrintInfo("鸡蛋煎好了"); 20 21 string bacon = await baconTask; 22 PrintInfo("培根煎好了"); 23 24 string toast = await toastTask; 25 PrintInfo("面包烤好了"); 26 //6. 倒一杯橙汁。 27 string oj = PourOJ(); 28 PrintInfo("橙汁倒好了"); 29 PrintInfo("早餐准备完毕!"); 30 watch.Stop(); 31 TimeSpan time = watch.Elapsed; 32 PrintInfo(string.Format("总运行时间为:{0}秒", time.TotalSeconds.ToString("0.00"))); 33 } 34 catch (AggregateException ex) { 35 PrintInfo("线程内部异常"); 36 PrintInfo(ex.StackTrace); 37 } 38 catch (Exception ex) 39 { 40 PrintInfo("其他异常"); 41 PrintInfo(ex.Message); 42 } 43 } 44 45 /// <summary> 46 /// 组合任务 全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论