I am trying to write a method that tries to execute an action but swallows any exceptions that are raised.
My first attempt is the following:
public static void SafeExecute(Action actionThatMayThrowException) {
try {
actionThatMayThrowException();
} catch {
// noop
}
}
Which works when called with a synchronous action:
SafeExecute(() => {
throw new Exception();
});
However fails when called with an asynchronous action:
SafeExecute(async () => {
await Task.FromResult(0);
throw new Exception();
});
Is is possible to write a method that handles both scenarios?
As we know, in asynchronous programming, control does not wait for the function's result and it executes the next line. So when the function throws an exception, at that moment the program control is out of the try-catch block.
To catch an exception that an async task throws, place the await expression in a try block, and catch the exception in a catch block. Uncomment the throw new Exception line in the example to demonstrate exception handling. The task's IsFaulted property is set to True , the task's Exception.
If we use the “await” keyword, the exception will be thrown: This solves the problem for a single simple task, but what if we have multiple tasks running within a method?
To correctly handle async
delegates you shouldn't use Action
(this will cause the lambda expression to be async void
which is dangerous and should be avoided), you should use Func<Task>
to be able to await
it:
public static async Task SafeExecute(Func<Task> asyncActionThatMayThrowException)
{
try
{
await asyncActionThatMayThrowException();
}
catch
{
// noop
}
}
This will solve the async
case, but not the synchronous case. You can't do both with a single method. To do that you would need a different method, but it can still call the async
one to enable reuse:
private static readonly Task<object> _completedTask = Task.FromResult<object>(null);
public static void SafeExecute(Action actionThatMayThrowException)
{
SafeExecute(() =>
{
actionThatMayThrowException();
return _completedTask;
});
}
I wouldn't actually recommend disregarding unhandled exceptions in this way. You should consider at least logging the exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With