[.NET] 使用 async & await 一步步将同步代码转换为异步编程

使用 async & await 一步步将同步代码转换为异步编程

【博主】反骨仔    【出处】http://www.cnblogs.com/liqingwen/p/6079707.html   

  上次,博主通过《利用 async & await 的异步编程》一文介绍了 async & await 的基本用法及异步的控制流和一些其它的东西。

  今天,博主打算从创建一个普通的 WPF 应用程序开始,看看如何将它逐步转换成一个异步的解决方案。你知道吗?使用 Visual Studio 2012 的新特性可以更加容易、直观的进行异步编程。

介绍

  这里通过一个普通的 WPF 程序进行讲解:

  一个文本框和一个按钮,左边文本框的内容为点击右键按钮时所产生的结果。

添加引用

  并且加上 demo 要用到的 using 指令

using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;

先创建一个同步的 WPF

  1.这是右边点击按钮的事件:

 1         /// <summary>
 2         /// 点击事件
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void btnSwitch_Click(object sender, RoutedEventArgs e)
 7         {
 8             //清除文本框所有内容
 9             tbResult.Clear();
10
11             //统计总数
12             SumSizes();
13         }

  2.我在 SumSizes 方法内包含几个方法:

    ① InitUrlInfoes:初始化 url 信息列表;

    ② GetUrlContents:获取网址内容;

    ③ DisplayResults:显示结果。

  (1)SumSizes 方法:统计总数。

 1         /// <summary>
 2         /// 统计总数
 3         /// </summary>
 4         private void SumSizes()
 5         {
 6             //加载网址
 7             var urls = InitUrlInfoes();
 8
 9             //字节总数
10             var totalCount = 0;
11             foreach (var url in urls)
12             {
13                 //返回一个 url 内容的字节数组
14                 var contents = GetUrlContents(url);
15
16                 //显示结果
17                 DisplayResults(url, contents);
18
19                 //更新总数
20                 totalCount += contents.Length;
21             }
22
23             tbResult.Text += $"\r\n         Total: {totalCount}, OK!";
24         }

  (2)InitUrlInfoes 方法:初始化 url 信息列表。

 1         /// <summary>
 2         /// 初始化 url 信息列表
 3         /// </summary>
 4         /// <returns></returns>
 5         private IList<string> InitUrlInfoes()
 6         {
 7             var urls = new List<string>()
 8             {
 9                 "http://www.cnblogs.com/",
10                 "http://www.cnblogs.com/liqingwen/",
11                 "http://www.cnblogs.com/liqingwen/p/5902587.html",
12                 "http://www.cnblogs.com/liqingwen/p/5922573.html"
13             };
14
15             return urls;
16         }

  (3)GetUrlContents 方法:获取网址内容。

 1         /// <summary>
 2         /// 获取网址内容
 3         /// </summary>
 4         /// <param name="url"></param>
 5         /// <returns></returns>
 6         private byte[] GetUrlContents(string url)
 7         {
 8             //假设下载速度平均延迟 300 毫秒
 9             Thread.Sleep(300);
10
11             using (var ms = new MemoryStream())
12             {
13                 var req = WebRequest.Create(url);
14
15                 using (var response = req.GetResponse())
16                 {
17                     //从指定 url 里读取数据
18                     using (var rs = response.GetResponseStream())
19                     {
20                         //从当前流中读取字节并将其写入到另一流中
21                         rs.CopyTo(ms);
22                     }
23                 }
24
25                 return ms.ToArray();
26             }
27
28         }

  (4)DisplayResults 方法:显示结果

 1         /// <summary>
 2         /// 显示结果
 3         /// </summary>
 4         /// <param name="url"></param>
 5         /// <param name="content"></param>
 6         private void DisplayResults(string url, byte[] content)
 7         {
 8             //内容长度
 9             var bytes = content.Length;
10
11             //移除 http:// 前缀
12             var replaceUrl = url.Replace("http://", "");
13
14             //显示
15             tbResult.Text += $"\r\n {replaceUrl}:   {bytes}";
16         }

测试结果图

时间: 2024-12-06 19:12:09

[.NET] 使用 async & await 一步步将同步代码转换为异步编程的相关文章

[译]async/await中使用阻塞式代码导致死锁

原文:[译]async/await中使用阻塞式代码导致死锁 这篇博文主要是讲解在async/await中使用阻塞式代码导致死锁的问题,以及如何避免出现这种死锁.内容主要是从作者Stephen Cleary的两篇博文中翻译过来. 原文1:Don'tBlock on Async Code 原文2:why the AspNetSynchronizationContext was removed 示例代码:async_await中使用阻塞式代码导致死锁.rar 一.async/await 异步代码运行流

异步async await 相关知识点总结以及代码练习

<script> const setTimeoutToPromise = duration => new Promise(resolve => { setTimeout(resolve, duration) }) export default { data() { return { mysrc: true } }, methods: { s1(a){ console.log(a) }, s2(a){ console.log(a) }, s3(a){ console.log(a) }

tornado 启动WSGI应用(Flask)使用多线程将同步代码变成异步

1.tornado是单线程的,同时WSGI应用又是同步的,如果我们使用Tornado启动WSGI应用,理论上每次只能处理一个请求都是,任何一个请求有阻塞,都会导致tornado的整个IOLOOP阻塞.如下所示,我们同时发出两个GET请求向http://127.0.0.1:5000/ 会发现第一个发出的请求会在大约5s之后返回,而另一个请求会在10s左右返回,我们可以判断,这两个请求是顺序执行的. from tornado.wsgi import WSGIContainer from tornad

Async/Await 异步编程中的最佳做法

近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的“第二步”:我假设您已阅读过有关这一方面的至少一篇介绍性文章. 本文不提供任何新内容,Stack Overflow.MSDN 论坛和 async/await FAQ 这类在线资源提供了同样的建议. 本文只重点介绍一些淹没在文档海洋中的最佳做法. 本文中的最佳做法更大程度上是“指导原则”,而不是实际规则. 其中每个指导原则都有一些例外情况

异步编程中的最佳做法(Async/Await) --转

近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的“第二步”:我假设您已阅读过有关这一方面的至少一篇介绍性文章. 本文不提供任何新内容,Stack Overflow.MSDN 论坛和 async/await FAQ 这类在线资源提供了同样的建议. 本文只重点介绍一些淹没在文档海洋中的最佳做法. 本文中的最佳做法更大程度上是“指导原则”,而不是实际规则. 其中每个指导原则都有一些例外情况

走进异步编程的世界 - 开始接触 async/await

[C#] 走进异步编程的世界 - 开始接触 async/await 走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $"" 来拼接字符串,相当于string.Format() 方法. 目录 What's 异步? async/await 结构 What’s 异步方法? 一.What's 异步? 启动程序时,系统会在内存中创建一个新的进程.进程是构

[C#] 走进异步编程的世界 - 开始接触 async/await(转)

原文链接:http://www.cnblogs.com/liqingwen/p/5831951.html 走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $"" 来拼接字符串,相当于string.Format() 方法. 目录 What's 异步? async/await 结构 What’s 异步方法? 一.What's 异步? 启动程序时,系

【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看看编译器到底在背后帮我们做了哪些复杂的工作的. 二.同步代码存在的问题 对于同步的代码,大家肯定都不陌生,因为我们平常写的代码大部分都是同步的,然而同步代码却存在一个很严重的问题,例如我们向一个Web服务器发出一个

.NET 中的 async/await 异步编程

前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关的知识,并整理成这篇博客,如果在阅读的过程中发现不对的地方,欢迎大家指正. 同步编程与异步编程 通常情况下,我们写的C#代码就是同步的,运行在同一个线程中,从程序的第一行代码到最后一句代码顺序执行.而异步编程的核心是使用多线程,通过让不同的线程执行不同的任务,实现不同代码的并行运行. 前台线程与后台线程 关于多线程,早在.NET2