在我们日常用async/await编程的时候,会遇到这个错误,“await运算符只能用于异步方法中”,就不明白原因,既然我已经使用await,已经等待任务完成,已经是同步了,为什么await还只能用在异步方法中。
最近正好看到一篇文章谈到async/await用法,就想到了这个问题,搜没有搜到。重新看了一遍微软官方说明,找到了答案。原来以前自己的理解是错误的。
await 运算符(C# 参考)中提到“await 运算符暂停对其所属的 async 方法的求值,直到其操作数表示的异步操作完成”,“当 await 运算符暂停其所属的异步方法时,控件将返回到方法的调用方”。应该是机器翻译的,不太好理解。参照他给出的例子,意思就是DownloadDocsMainPageAsync方法中遇到await,就暂停执行DownloadDocsMainPageAsync方法了,将继续执行DownloadDocsMainPageAsync方法的调用方Main方法,直至Main方法需要DownloadDocsMainPageAsync的结果。
使用 Async 和 Await 的异步编程中提到“不要阻塞,而要 await”,自己通过实验证实,使用了await关键字,并不会阻塞主线程GUI响应。也就是这一段描述的意思“在煎鸡蛋或培根时,此代码不会阻塞。 不过,此代码也不会启动任何其他任务。 你还是会将面包放进烤面包机里,然后盯着烤面包机直到面包弹出。 但至少,你会回应任何想引起你注意的人。 在接受了多份订单的一家餐馆里,厨师可能会在做第一份早餐的同时开始制作另一份早餐。”使用了await,暂停当前函数的执行,但是调用方会继续执行,开始做另一份早餐。
另外一个问题。
用async来修饰一个方法,方法内部必须含有await修饰的方法,如果方法内部没有await关键字修饰的表达式,哪怕函数被async修饰也只能算作同步方法,执行的时候也是同步执行的。
自己测试了一下只将方法定义为async的,内部不使用await,会阻塞。这个也不难理解,async修饰的函数不会自动创建新的线程去执行自己的代码,否则也就不需要await了,整个都是异步的了。
不知道有没有纰漏呢,欢迎拍砖。