咨询:C#中.ContinueWith(object state)与async await写法的优劣对比
两种C#异步解密方法的优劣分析
先把你没写完的方法二补全(这应该是.NET异步编程里最常规的async/await+using实现方式):
// 方法二(补全后) public async Task<string> DecryptAsync(string encrypted) { using (SymmetricAlgorithm aes = this.GetAes()) { return await this.DecryptAsync(aes, encrypted); } }
下面从你关心的三个维度逐一对比:
1. 美观性
方法二的优势非常明显。它的代码结构线性直观,using语句清晰标记了SymmetricAlgorithm实例的生命周期,任何人扫一眼就能明白资源会被自动释放,完全不需要额外梳理逻辑。
而方法一用ContinueWith嵌套的写法,把资源释放和业务逻辑强行绑定在一起,代码显得臃肿绕弯,需要花额外时间理解参数传递和执行时机,可读性差很多。
2. 惯用性
方法二完全贴合.NET异步编程的最佳实践:
async/await是.NET 4.5之后主推的异步写法,它让异步代码拥有和同步代码一致的线性结构,大幅降低了异步编程的心智负担。using语句是.NET处理IDisposable资源的标准方式,编译器会自动生成try/finally逻辑,确保无论是否出现异常,资源都会被正确释放。
方法一的ContinueWith属于早期TPL(任务并行库)的写法,在async/await普及后,除非有特殊的线程调度需求,否则几乎不会再用这种方式处理异步后的资源清理——它不仅写法繁琐,还容易因为默认TaskScheduler的行为产生意料之外的问题(比如在非预期的线程上执行资源释放)。
3. 性能
两者的性能差异微乎其微,但方法二更稳妥:
- 方法二中的资源释放逻辑是在
await完成后,在当前异步状态机的上下文里同步执行,没有额外的线程调度开销。 - 方法一的
ContinueWith如果不指定TaskScheduler,默认会使用TaskScheduler.Current,可能导致资源释放逻辑在不同线程执行,虽然对SymmetricAlgorithm的Dispose影响不大,但这种额外调度完全没有必要。
更重要的是,方法二的代码复杂度低,长期维护时更不容易出现资源泄漏、异常处理遗漏等问题,间接避免了这类问题带来的隐性性能损耗。
总结
强烈推荐方法二,它既符合.NET的惯用写法,又具备极佳的可读性,性能上也没有劣势,是异步场景下处理可释放资源的标准方案。
内容的提问来源于stack exchange,提问作者Jesse C. Slicer
相关产品推荐
相关产品推荐

