C#异步任务中直接返回Task和用await返回有何区别?哪种写法正确?
两种写法的核心区别
- 异常抛出时机不同
第一种直接返回Task的写法,要是_getter为null、或者GetAsync()方法在返回Task之前就抛出同步异常,异常会在你调用DoSomeWork()的瞬间直接抛出,不会被封装到返回的Task对象里。
第二种加async/await的写法,不管是同步阶段的异常还是异步执行阶段的异常,全部都会被封装到返回的Task中,只有你await这个Task的时候才会抛出异常。 - 运行开销不同
第一种写法不会触发编译器生成异步状态机,没有额外的内存分配和状态切换开销,性能略优。第二种写法会生成对应的异步状态机类,会有极少量的额外开销,绝大多数场景下可以忽略,但高频调用场景下差异会被放大。 - 资源生命周期适配不同
如果你的方法内部存在using声明的本地资源(比如数据库连接、文件流等),第一种直接返回Task的写法会在方法返回时立刻释放using资源,等后续你await Task的时候,资源已经被释放,会导致异步操作失败。第二种async/await的写法会等await的异步操作执行完成后,再释放using声明的本地资源,符合资源生命周期的预期。
适用场景(没有绝对的“正确”,按需选择)
- 如果你的方法只是单纯的异步调用转发,没有中间逻辑、没有本地需要管理的资源、也不需要统一处理异常,直接返回Task的写法更简洁高效,是没问题的。
- 如果你的方法有本地资源需要管理、需要在方法内部捕获处理异常、或者你对外暴露的是类库公共API,需要保证所有异常都封装到Task中统一行为,就必须使用
async/await的写法。
内容的提问来源于stack exchange,提问作者barakcaf
相关产品推荐
相关产品推荐

