捕获异步lambda引发的异常

时间:2014-08-14 09:19:27

标签: c# .net exception-handling task-parallel-library async-await

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

我的第一次尝试如下:

public static void SafeExecute(Action actionThatMayThrowException) {
    try {
        actionThatMayThrowException();
    } catch {
        // noop
    }
}

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

SafeExecute(() => { 
    throw new Exception(); 
});

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

SafeExecute(async () => { 
    await Task.FromResult(0);
    throw new Exception(); 
});

是否可以编写一个处理这两种情况的方法?

1 个答案:

答案 0 :(得分:14)

要正确处理async个委托,你不应该使用Action(这会导致lambda表达式async void这是危险的should be avoided),你应该使用Func<Task>能够await

public static async Task SafeExecute(Func<Task> asyncActionThatMayThrowException)
{
    try
    {
        await asyncActionThatMayThrowException();
    }
    catch
    {
        // noop
    }
}

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

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

public static void SafeExecute(Action actionThatMayThrowException)
{
    SafeExecute(() =>
    {
        actionThatMayThrowException();
        return _completedTask;
    });
}

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