捕获异步lambda引发的异常

kim*_*gro 12 .net c# exception-handling task-parallel-library async-await

我试图编写一个尝试执行操作但吞下任何引发的异常的方法.

我的第一次尝试如下:

public static void SafeExecute(Action actionThatMayThrowException) {
    try {
        actionThatMayThrowException();
    } catch {
        // noop
    }
}
Run Code Online (Sandbox Code Playgroud)

使用同步操作调用时有效:

SafeExecute(() => { 
    throw new Exception(); 
});
Run Code Online (Sandbox Code Playgroud)

但是在使用异步操作调用时失败:

SafeExecute(async () => { 
    await Task.FromResult(0);
    throw new Exception(); 
});
Run Code Online (Sandbox Code Playgroud)

有可能编写一个处理这两种情况的方法吗?

i3a*_*non 14

要正确处理好async,你不应该使用委托Action(这将导致lambda表达式是async void这是危险的,应该避免),你应该使用Func<Task>能够为await它:

public static async Task SafeExecute(Func<Task> asyncActionThatMayThrowException)
{
    try
    {
        await asyncActionThatMayThrowException();
    }
    catch
    {
        // noop
    }
}
Run Code Online (Sandbox Code Playgroud)

这将解决async案例,但不是同步案例.你不能用一种方法做到这两点.要做到这一点,你需要一个不同的方法,但它仍然可以调用async一个方法来启用重用:

private static readonly Task<object> _completedTask = Task.FromResult<object>(null);

public static void SafeExecute(Action actionThatMayThrowException)
{
    SafeExecute(() =>
    {
        actionThatMayThrowException();
        return _completedTask;
    });
}
Run Code Online (Sandbox Code Playgroud)

我实际上不建议以这种方式忽视未处理的异常.您应该考虑至少记录异常.