C#面试题更新 2026-08-05

请说明在 C# 的 catch 和 finally 块中能否使用 await,以及如何正确运用它来处理异步异常?

风险判断技术原理C#

考察说明

考查对 C# 异步编程中异常处理细节的理解,特别是 catch 和 finally 块内使用 await 的合法性和注意事项。

回答思路

  1. 【回答框架 1】在 C# 中,catch 和 finally 块中可以使用 await,因为 async 方法中的这些块是异步上下文的一部分。但要注意,如果 catch 或 finally 块中的 await 抛出异常,会掩盖原始异常,导致原始异常信息丢失。
  2. 【回答框架 2】在 catch 块中,常用模式是使用 await 进行日志记录或清理操作,但需确保这些操作不抛出异常,或者将原始异常与 await 的异常一起处理,例如使用 ExceptionDispatchInfo 或 AggregatedException 来保留上下文。
  3. 【回答框架 3】在 finally 块中,await 用于异步清理资源,但需谨慎,因为 finally 中的异常会替换掉正在传播的异常。建议在 finally 中避免抛出异常,或使用 try-catch 包裹 await 操作。
  4. 【回答框架 4】为了安全地处理异步异常,可以在 catch 块中使用 await 时,将原始异常存储,然后重新抛出或合并,例如使用 ExceptionDispatchInfo.Capture(originalException).Throw() 来保留原始堆栈。
  5. 【关键点 1】catch 和 finally 块中可以使用 await,前提是所在方法被标记为 async。
  6. 【关键点 2】catch 块中的 await 如果抛出异常,会覆盖原始异常,需要额外处理以避免信息丢失。
  7. 【关键点 3】finally 块中的 await 若引发异常,会中断原始异常传播,应避免或捕获该异常。
  8. 【易错点 1】在 catch 或 finally 中直接使用 await 而忽略其可能抛出的异常,导致原始异常被掩盖。
  9. 【易错点 2】在 finally 中执行异步操作时未处理异常,导致程序在异常路径上终止。
  10. 【易错点 3】认为异步方法中的 finally 块无法使用 await,实际上只要方法为 async 即可。