【博主】反骨仔 【出处】http://www.cnblogs.com/liqingwen/p/6079707.html
上次,博主通过《利用 async & await 的异步编程》一文介绍了 async & await 的基本用法及异步的控制流和一些其它的东西。
今天,博主打算从创建一个普通的 WPF 应用程序开始,看看如何将它逐步转换成一个异步的解决方案。你知道吗?使用 Visual Studio 2012 的新特性可以更加容易、直观的进行异步编程。
Foundation (WPF) application that sums the number of bytes in a list of websites.">
这里通过一个普通的 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 }
测试结果图