使用时注意点
1 private async void button5_Click(object sender, EventArgs e)
2 {
3 /
4 string i1 = await F1Async();
5 MessageBox.Show("i1=" + i1);
6 string i2 = await F2Async();
7 MessageBox.Show("i2=" + i2);
8 /
9 Task[span style="color: rgba(0, 0, 255, 1)">string
10 Task[span style="color: rgba(0, 0, 255, 1)">string
11 string i1 = await //代码效果参考:http://www.lyjsj.net.cn/wz/art_23116.html
task1;12 MessageBox.Show("i1=" + i1);
13 string i2 = await task2;
14 MessageBox.Show("i2=" + i2);
15 }
16
17 static Task[span style="color: rgba(0, 0, 255, 1)">string
18 {
19 MessageBox.Show("F1 Start");
20 return Task.Run(() => {
21 System.Threading.Thread.Sleep(1000);
22 MessageBox.Show("F1 Run");
23 return "F1";
24 });
25 }
26
27 static Task[span style="color: rgba(0, 0, 255, 1)">string
28 //代码效果参考:http://www.lyjsj.net.cn/wz/art_23124.html
{29 MessageBox.Show("F2 Start");
30 return Task.Run(() => {
31 System.Threading.Thread.Sleep(2000);
32 MessageBox.Show("F2 Run");
33 return "F2";
34 });
35 }
如上两个异步方法,在调用时,第一种调用提示框会按步骤弹出,而第二种则混乱的弹出,但这也不难理解因为多线程本来就是分片执行不按代码顺序;
第二种写法的await是作为一个最后的保险作用,它的意义在于如果开始就执行了ok,如果没执行则这步该执行了
不能使用async修饰而要调用异步方法怎么办?
出现这种情况比较少,此时可以获得Task类型的返回值,获取Task.Result()方法,终止异步;
但请注意尽量少的使用Result()方法,他会造成数据上下文的死锁问题。
如果返回值就是一个立即可以随手可得的值,那么就用 Task.FromResult();
异步方法的风格转换
Task.Factory.FromAsync()把 IAsyncResult 转换为 Task,这样 APM 风格的 api 也可以用 await 来调用
await修饰与并发执行的顺序
被await修饰的异步方法,一定会按照顺序执行并结束,所以如果没有顺序要求可以不使用await修饰并发任务
eg
1 private async void button1_Click(object sender, EventArgs e)
2 {
3 HttpClient hc = new HttpClient();
4 var task1 = hc.GetStringAsync(textBox1.Text);
5 var task2 = hc.GetStringAsync(textBox2.Text);
6 var task3 = hc.GetStringAsync(textBox3.Text);
7 Task.WaitAll(task1, task2, task3);
8 label1.Text = task1.Result.Length.ToString();
9 label2.Text = task2.Result.Length.ToString();
10 label3.Text = task3.Result.Length.ToString();
11 }
View Code
在接口中使用await
在接口定义是不能给接口做await修饰,然而为了增加可读性,在方法明后添加async的特殊表示,在实现类中去添加await修饰即可
异常处理
TPL中,如果程序中出现异常,除非进行try...catch,否则有可能是感觉不到出了异常....
TPL中有时会抛出AggregateException可以同时catch住多个异常,这通常发生在并行多个任务的情况下
TPL与asp.net mvc
1. 返回值改为Task即可,如果方法标记为async,连自己创建Task都省了
1 public async Task Index()
2 {
3 return View();
4 }
View Code
2. 为什么asp.net中用mvc能提升系统性能?
准确来讲,不是提升性能,不会提高访问速度,而是提升服务器的“吞吐量”,也就是可以处理的并发请求数
TPL常见的误区
如果用了异步,那么就要async到底;async具有传染性;
如果在使用异步api中掺杂了同步方法,则会打断异步方法,有可能造成数据死锁而且还会降低系统性能,so,不要轻易使用Wait、WaitAll
只要await、WhenAll不要task.Result、Wait、WaitAll