异步编程 async、await

发布时间 2023-11-21 08:57:41作者: 陈醋当墨写尽人生酸楚

1、使用async修饰符标记的方法称为异步方法

1) 异步方法的返回值一般是Task<T>,T是真正的返回值类型,Task<int>。惯例:异步方法名字以Async结尾。

2) 即使方法没有返回值,也最好把返回值声明为非泛型的Task。 

3) 调用泛型方法时,一般在方法前加上await关,这样拿到的返回值就是泛型指定的T类型;

4) 异步方法的“传染性”:一个方法中如果有await调用,则这个方法也必须修饰为async

2、async 方法的缺点

  • 异步方法会生成一个类,运行效率没有普通方法高;
  • 可能会占用非常多的线程;

3、异步方法使用注意

  优化:直接返回异步方法Task<T>,只是当成普通的方法调用,运行效率更高,不会造成线程浪费。

  禁用:异步方法Task<T>的 Wait()【无返回值】,Result()【有返回值】,存在死锁风险,尽量不用

 

  优化:await Task.Delay(毫秒数):延迟,不会卡主线程。【异步方法中暂停使用】

  禁用:Thread.Sleep(毫秒数):延迟,会阻塞主线程,降低并发。

  返回值为Task的不一定都要标注 async ,标注 async 只是让我们更方便 await 而已。

  如果一个异步方法只是对别的异步方法调用的转发,并没有太多复杂的逻辑(比如等待A的结果,在调用B,把A调用的返回值拿到内部做一些处理再返回),那么就可以去掉 async 关键字。

4、特殊处理

  有时需要提前终止任务比如:请求超时、用户取消请求。

  很多异步方法都有CancellationToken 参数,用于获得提前终止执行的信号。

  CancellationToken 结构体常用的内容

  • bool IsCancellationRequested 是否被取消
  • ThrowIfCancellationRequested() 如果异步任务被取消,执行这句话就抛异常。

  .Net Core开发中,一般不需要自己处理CancellationToken、CancellationTokenSource这些,只要做到"能转发CancellationToken就转发"即可。