使用 async & await 一步步將同步代碼轉換為非同步編程 【博主】反骨仔 【出處】http://www.cnblogs.com/liqingwen/p/6079707.html 序 上次,博主通過《利用 async & await 的非同步編程》一文介紹了 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 }
測試結果圖