1. C#5.0 加入了async, await关键字. async
是在声明异步方法时使用的修饰符, 声明放在返回值之前即可,await
表达式则负责消费异步操作, 不能出现在catch或finally块, 非异步匿名函数(没有用async声明的匿名方法或者lambda表达式), lock语句或不安全的代码中使用。
ps:这些约束条件是为了保证安全,特别是关于锁的约束。如果你希望在异步操作完成时持有锁,那么应该重新设计你的代码。不要通过在try/finally
块中手动调用Monitor.TryEnter
和Monitor.Exit
的方式绕过编译器的限制,而应该实现代码的更改,这样在操作过程中就不再需要锁了。如果此时的情况不允许代码的改变,则可考虑使用SemaphoreSlim
和它的WaitAsync
方法来代替。
2. 所有用async修饰的异步方法, 参数都不可以使用out 或者 ref 修饰符. 返回值必须是void, task, task<T>. 一般为task. 因为可以让调用者监控异步操作的状态.
3. await的主要目的是在等待耗时操作完成时避免阻塞。代码总是在执行到await的时候就开始返回了, 并且到达await之后会校验结果是否存在 如果结果不存在, 会安排给一个后续操作, 这个后续操作会记录位置,状态, 然后代码回到UI主线程继续运行, 此时button.click方法实际上已经执行结束. 现在的调用栈就是windows form的事件循环, 当await标记的结果得到时会继续运行之后的代码.
下面是我写的一个demo小测试程序:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Threading;
7 using System.Net.Http;
8 using System.Net;
9 using System.Diagnostics;
10 using System.IO;
11
12 namespace DennisDemos.Demos
13 {
14 class AsyncDemo
15 {
16 public void Run()
17 {
18 //var result = Test1();
19 //Console.WriteLine(result.Result);// 必须等到结果之后才能继续执行下面的代码. 所以result是同步的.
20 //Console.WriteLine("test1 end");
21 Console.WriteLine("MainAsync start.");
22 var result2 = MainAsync();
23
24 Console.WriteLine("MainAsync end.");
25 while (!result2.IsCompleted)
26 {
27 Thread.Sleep(1000);
28 Console.WriteLine("waiting..");
29 }
30 Console.WriteLine("end.");
31 }
32 static async Task MainAsync()
33 {
34 Task<string> task = ReadFileAsync("LogicDocument_DocAveLoadBalance.docx"); //❶ 开始异步读取
35 try
36 {
37 Console.WriteLine("start to wait reads file reult.");
38 string text = await task; //❷ 等待内容
39 Thread.Sleep(10000);
40 Console.WriteLine("File contents");
41 }
42 catch (IOException e) //❸ 处理IO失败
43 {
44 Console.WriteLine("Caught IOException: {0}", e.Message);
45 }
46 }
47
48 static async Task<string> ReadFileAsync(string filename)
49 {
50 Console.WriteLine("start to read file async.");
51 using (var reader = File.OpenText(filename)) //❹ 同步打开文件
52 {
53 var result = await reader.ReadToEndAsync();
54 Thread.Sleep(1000);
55 Console.WriteLine("get read file async result.");
56 return result;
57 }
58 }
59 }
60 }
to be continued..
来源:oschina
链接:https://my.oschina.net/u/4407777/blog/3909721