TryCatchFinally

Version >= 6

从 C#6.0 开始,await 关键字现在可以在 catchfinally 块中使用。

try {
   var client = new AsyncClient();
   await client.DoSomething();
} catch (MyException ex) {
   await client.LogExceptionAsync();
   throw;
} finally {
   await client.CloseAsync();
}

Version < 6.0

在 C#6.0 之前,你需要执行以下操作。请注意,6.0 还使用 Null Propagating 运算符清除了空检查。

AsynClient client;
MyException caughtException;
try {
     client = new AsyncClient();
     await client.DoSomething();
} catch (MyException ex) {
     caughtException = ex;
}

if (client != null) {
    if (caughtException != null) {
       await client.LogExceptionAsync();
    }
    await client.CloseAsync();
    if (caughtException != null) throw caughtException;
}

请注意,如果等待 async 创建的任务(例如 Task.Run 创建的任务),某些调试器可能会破坏任务抛出的异常,即使它看起来是由周围的 try / catch 处理的。发生这种情况是因为调试器认为它对用户代码未处理。在 Visual Studio 中,有一个名为 Just My Code 的选项,可以禁用该选项以防止调试器在这种情况下中断。