从版本5.0开始,C#引入了async/await的异步编程模式,大大简化了异步编程的难度,使我们摆脱了回调函数、事件等传统的方式,可以使用类似同步编程的方式进行异步编程,这里通过一个小例子说明这种编程方式以及需要注意的地方。
异步编程的主要目的是当执行到耗时较多的过程时,先启动这个过程,然后继续执行后续代码,当需要这个过程的返回的值时,再进行等待。这些耗时的过程可能是从网上下载文件,或者从数据库读入初始化数据等等。使用async/await方式编程时,需要使用async声明需要异步执行的过程,比如:
1 | async static Task<string> DoTask(int i) |
async返回的类型是Task或者Task<>,如果没有返回,可以是void。需要注意的是:async声明的函数或者方法中,必须有使用await语句执行的异步代码,否则这个函数或过程会被同步执行。反过来,使用await语句调用异步执行代码的函数,也必须声明为async。在同步函数中可以直接调用异步函数,使用Task.Result获取结果值,比如:
1 | string res=DoTask(10).Result; |
下面的代码启动若干异步任务:
1 | using System; |
从执行结果看,这些任务不是在同一线程执行的:
异步编程下需要注意的是访问公用变量的问题,如果多个异步任务对同一公用变量进行修改的化,结果可能不可预测,我们在这里定义了一个简单的公用变量,在异步任务中对它进行赋值,最后的结果是不可预测的,上次执行时结果是4,这次执行就变成了2: