异步多线程 await/async
await/async
是一个语法糖,本身不会产生新的线程,但是依托于Task而存在,所以执行时,也是会有多线程。
async可以没有await,但await一定要有async,并且只能只能出现在task前面。
原来没有返回值的方法,用await/async修饰后,会返回Task
原来有返回值T的方法,修饰后,会返回Task<T>
一般不推荐修饰void方法,不然调用处无法再次await
看看这个到底有什么效果
先来个简单的,不用await/async修饰,创建一个类,用task实现多线程输出结果。
public class AwaitAsync { public void Show() { Console.WriteLine("Show开始线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); NoReturnMethod(); Console.WriteLine("Show结束线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); } public void NoReturnMethod() { Console.WriteLine("NoReturnMethod开始线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); Task.Run(() => { Console.WriteLine("NoReturnMethod Task 开始线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); Thread.Sleep(2000); Console.WriteLine("NoReturnMethod Task 结束线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); }); Console.WriteLine("NoReturnMethod结束线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); } }
这没啥问题吧?
那么加上Await/async试试
public async void AsyncNoReturnMethod() { Console.WriteLine("NoReturnMethod开始线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); await Task.Run(() => { Console.WriteLine("NoReturnMethod Task 开始线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); Thread.Sleep(2000); Console.WriteLine("NoReturnMethod Task 结束线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); }); Console.WriteLine("NoReturnMethod结束线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); }
线程1遇到await后自行返回去执行 输出“Show结束线程:1”这一步了,await后面的代码虽然不在Task.Run中,但是依然被它的线程3执行,这种感觉,是不是很像之前讲Task时说到的回调。
从编写代码的感受来说,是在用同步的顺序方式编写异步代码,你读代码的时候可以确定,await后面的代码一定是在多线程代码执行完成后才执行,不需要通过阻塞的方式实现,也不需要一层层的套回调方法,读起来很舒服。