1 异步方法需要Async关键字修饰
2 异步方法的返回类型只能是void或Task
3 返回值类型是T时,异步方法返回类型必须是Task
4 await可以用于async方法和 async方法中的task(通过3、4两点大家应该能猜到,异步方法本身其实就是一个Task或者说和自己内部的Task在同一线程)
5 只有异步方法内使用了 (await关键词描述的)(有返回值的线程Task)才能体现异步方法的优势
总结:
【意义】异步方法的意义就是保证一个进程使用多线程多次执行一个方法时,不会因为其中某一次执行阻塞调用进程
【原理】利用方法内Task调用新线程,await使方法内等待Task结果时调用进程不被阻塞,多次调用相当于多个线程并行。(不被阻塞的原因应该是异步方法本身就和内部的Task跑在一个线程里)
【区别】普通方法只用Task也可以并行,当方法内需要Task返回值时,等待Task结果就会阻塞调用进程。
【应用】主要应用在没有返回值,使用线程且需要线程返回结果的方法。
一些分析:
1.异步方法有返回值会怎样?
因为异步方法返回类型是Task,所以获取返回值只能await或者.Result,两者都会让当前方法等待。
2.那么异步方法是不是没有作用了?
如果是用.Result获取,那么是。如果是await就不一定了。await只能在async方法中使用,所以await获取异步方法返回值的方法也是异步的,再往上最终只能肯定是一个普通方法调用异步方法。是否有用取决于普通方法内调用最上层异步方法的方式。
3.为什么返回值类型是T,方法返回类型需要是Task?
要达到异步方法内等待线程结果不阻塞调用进程,这个方法本身就应该在线程中执行。所以不管返回类型是什么,放到Task中运行后返回的是Task。这样被调用时相当于一个Task.Run(),也就可以实现异步方法await了。
4.为什么要实现异步方法await可等待?
异步方法的await其实第二点已经分析了,实现异步方法await可以允许异步方法内继续调用异步方法,把异步操作从底层向上层传递。而能够传递到的最上层是什么,是static void Main(),所以最终还是普通方法调用异步方法。也就是说不能继续使用await等待异步方法的结果了,当最上层不关注返回结果时,不管内部有多少次await异步方法的调用,依然还是多线程的并行。如果最上层非要关注异步方法的返回结果,用.Result获取其结果,那我无话可说。
5.关于Async和await。
await其实不光是一个简单的让下一行代码等待异步方法或Task结果的关键字。应该理解成一个扩大当前Task代码执行范围的命令。
从最开始的await Task让整个异步方法B都能在Task中运行(所以普通方法调用异步方法B时,B内await Task结果就不会阻塞调用进程)。
到异步方法A中await异步方法B让异步方法A和B都在同一Task内运行(所以普通方法调用异步方法A时,A内await异步方法B的结果和B内await Task的结果就不会阻塞调用进程)
Async用于标识一个方法是异步方法,约束其返回类型为Task。也就说内部可以使用await,且方法本身是放到Task中执行的,所以代码返回类型T,方法的返回类型却是Task。
最后一定要区别异步方法和普通多线程方法的用处,他们的关键区别就是是否需要单独等待线程的执行结果。不要把异步方法当多线程方法用了。