原文链接 : http://www.cnblogs.com/liqingwen/p/6079707.html
http://www.cnblogs.com/liqingwen/p/6079707.html
序
》该篇点睛之作介绍了 async & await 的基本用法及异步的控制流和一些其它的东西。
异步的解决方案。
目录
介绍
这里通过一个普通的 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 方法:统计总数。
(2)InitUrlInfoes 方法:初始化 url 信息列表。
(3)GetUrlContents 方法:获取网址内容。
(4)DisplayResults 方法:显示结果
测试结果图
全部显示需要耗费数秒的时间即使不想再继续等待并关闭程序都会很困难。
将上面的 demo 逐步转换为异步方法
1.GetUrlContents 方法 => GetUrlContentsAsync 异步方法
(1) 将 GetResponse 方法改成 GetResponseAsync 方法:
//var response = req.GetResponse(); var response = req.GetResponseAsync()
(2)在 GetResponseAsync 方法前加上 await:
GetResponseAsync 方法。
//var response = req.GetResponseAsync() var response = await req.GetResponseAsync()
response。
上面的内容也可以拆分成下面的内容:
//Task<WebResponse> responseTask = req.GetResponseAsync(); //var response = await responseTask;
responseTask WebResponse 值。
CopyToAsync 时,请先暂时忽略该错误。
-
更改调用 CopyToAsync方法的名称。
-
CopyToAsync。
//rs.CopyTo(ms); await rs.CopyToAsync(ms);
(4)也要修改 Tread.Sleep。Thread.Sleep 是同步延迟,Task.Delay 异步延迟;Thread.Sleep 会阻塞线程,而Task.Delay 不会。
//Thread.Sleep(300); await Task.Delay(300);
(5)异步方法 。
//private async byte[] GetUrlContents(string url) //private async Task<byte[]> GetUrlContents(string url) private async Task<byte[]> GetUrlContentsAsync(string url)
Task 返回类型理解为“任务 (失效)”。
在方法签名中进行以下更改:
-
Task<byte[]>。
-
GetURLContentsAsync 重命名。
(6)这是修改后的整体方法
2.仿造上述过程将 SumSizes 方法 => SumSizesAsync 异步方法。
1 /// <summary>
2 /// 异步统计总数
3 /// </summary>
4 private async Task SumSizesAsync()
5 {
6 //加载网址
7 var urls = InitUrlInfoes();
8
9 //字节总数
10 var totalCount = 0;
11 foreach (var url in urls)
12 {
13 //返回一个 url 内容的字节数组
14 var contents = await GetUrlContentsAsync(url);
15
16 //显示结果
17 DisplayResults(url, contents);
18
19 //更新总数
20 totalCount += contents.Length;
21 }
22
23 tbResult.Text += $"\r\n Total: {totalCount}, OK!";
24 }
3.再修改下 btnSwitch_Click
这里为防止意外地重新输入操作,先在顶部禁用按钮,在最终完成时再启用按钮。Task。
1 /// <summary>
2 /// 异步点击事件
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private async void btnSwitch_Click(object sender, RoutedEventArgs e)
7 {
8 btnSwitch.IsEnabled = false;
9
10 //清除文本框所有内容
11 tbResult.Clear();
12
13 //统计总数
14 await SumSizesAsync();
15
16 btnSwitch.IsEnabled = true;
17 }
4.其实可以采用 .NET 自带的 GetByteArrayAsync 异步方法替换我们自己写的 GetUrlContentsAsync 异步方法,之前只是为了演示的需要。
var hc = new HttpClient() { MaxResponseContentBufferSize = 1024000 };
//var contents = await GetUrlContentsAsync(url);
var contents = await hc.GetByteArrayAsync(url);
这时,项目的变换从同步到异步操作已经完成。
修改后的效果差异:关闭按钮取消了操作 (右上角的 X)。
同系列的随笔
【参考引用】微软官方文档图片
- 感谢您的阅读。喜欢的、有用的就请大哥大嫂们高抬贵手“推荐一下”吧!你的精神支持是博主强大的写作动力。欢迎转载!
- 博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。
- 我的博客:http://www.cnblogs.com/liqingwen/
http://www.cnblogs.com/liqingwen/p/6079707.html
序
》该篇点睛之作介绍了 async & await 的基本用法及异步的控制流和一些其它的东西。
异步的解决方案。
目录
介绍
这里通过一个普通的 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 方法:统计总数。
(2)InitUrlInfoes 方法:初始化 url 信息列表。
(3)GetUrlContents 方法:获取网址内容。
(4)DisplayResults 方法:显示结果
测试结果图
全部显示需要耗费数秒的时间即使不想再继续等待并关闭程序都会很困难。
将上面的 demo 逐步转换为异步方法
1.GetUrlContents 方法 => GetUrlContentsAsync 异步方法
(1) 将 GetResponse 方法改成 GetResponseAsync 方法:
//var response = req.GetResponse(); var response = req.GetResponseAsync()
(2)在 GetResponseAsync 方法前加上 await:
GetResponseAsync 方法。
//var response = req.GetResponseAsync() var response = await req.GetResponseAsync()
response。
上面的内容也可以拆分成下面的内容:
//Task<WebResponse> responseTask = req.GetResponseAsync(); //var response = await responseTask;
responseTask WebResponse 值。
CopyToAsync 时,请先暂时忽略该错误。
-
更改调用 CopyToAsync方法的名称。
-
CopyToAsync。
//rs.CopyTo(ms); await rs.CopyToAsync(ms);
(4)也要修改 Tread.Sleep。Thread.Sleep 是同步延迟,Task.Delay 异步延迟;Thread.Sleep 会阻塞线程,而Task.Delay 不会。
//Thread.Sleep(300); await Task.Delay(300);
(5)异步方法 。
//private async byte[] GetUrlContents(string url) //private async Task<byte[]> GetUrlContents(string url) private async Task<byte[]> GetUrlContentsAsync(string url)
Task 返回类型理解为“任务 (失效)”。
在方法签名中进行以下更改:
-
Task<byte[]>。
-
GetURLContentsAsync 重命名。
(6)这是修改后的整体方法
2.仿造上述过程将 SumSizes 方法 => SumSizesAsync 异步方法。
1 /// <summary>
2 /// 异步统计总数
3 /// </summary>
4 private async Task SumSizesAsync()
5 {
6 //加载网址
7 var urls = InitUrlInfoes();
8
9 //字节总数
10 var totalCount = 0;
11 foreach (var url in urls)
12 {
13 //返回一个 url 内容的字节数组
14 var contents = await GetUrlContentsAsync(url);
15
16 //显示结果
17 DisplayResults(url, contents);
18
19 //更新总数
20 totalCount += contents.Length;
21 }
22
23 tbResult.Text += $"\r\n Total: {totalCount}, OK!";
24 }
3.再修改下 btnSwitch_Click
这里为防止意外地重新输入操作,先在顶部禁用按钮,在最终完成时再启用按钮。Task。
1 /// <summary>
2 /// 异步点击事件
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private async void btnSwitch_Click(object sender, RoutedEventArgs e)
7 {
8 btnSwitch.IsEnabled = false;
9
10 //清除文本框所有内容
11 tbResult.Clear();
12
13 //统计总数
14 await SumSizesAsync();
15
16 btnSwitch.IsEnabled = true;
17 }
4.其实可以采用 .NET 自带的 GetByteArrayAsync 异步方法替换我们自己写的 GetUrlContentsAsync 异步方法,之前只是为了演示的需要。
var hc = new HttpClient() { MaxResponseContentBufferSize = 1024000 };
//var contents = await GetUrlContentsAsync(url);
var contents = await hc.GetByteArrayAsync(url);
这时,项目的变换从同步到异步操作已经完成。
修改后的效果差异:关闭按钮取消了操作 (右上角的 X)。
同系列的随笔
【参考引用】微软官方文档图片