Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to Wait for a TPL Task without in throwing an exception?

Some of us prefer to code in an exception-light style. However, if you wait for a Task Parallel Library task, and the task threw an exception, it will throw an exception on the calling thread as well. Is there a (preferably standard) way to avoid this behaviour and just check the response for exceptions when you get it back?

like image 957
Julian Birch Avatar asked Aug 10 '15 10:08

Julian Birch


People also ask

How to handle exceptions in Task?

Exceptions are propagated when you use one of the static or instance Task. Wait methods, and you handle them by enclosing the call in a try / catch statement. If a task is the parent of attached child tasks, or if you are waiting on multiple tasks, multiple exceptions could be thrown.

How to throw exception in Task c#?

try { t. Start(); await t; } catch (Exception e) { // When awating on the task, the exception itself is thrown. // in this case a regular Exception. } } In TPL, When throwing an exception inside a Task, it's wrapped with an AggregateException.

What happens when a task throws an exception?

If Bar throws an exception, it will be thrown right at the point where you call it. However, if the Task that Bar returns wraps an exception, what happens depends on your version of . NET runtime - for .


2 Answers

You can use Task.WaitAny like:

        var task = Task.Run(() =>
        {
            // ...
            throw new Exception("Blah");
        });
        Task.WaitAny(task);
        if (task.IsFaulted)
        {
            var error = task.Exception;
            // ...
        }
        else if (task.IsCanceled)
        {
            // ...
        }
        else
        {
            // Success
        }
like image 183
Ivan Stoev Avatar answered Sep 23 '22 20:09

Ivan Stoev


You can't wait on a faulted task without raising an exception. But you can wait on a continuation to that task, which will complete only after the original task completed without raising an exception:

public static Task SwallowExceptions(this Task task)
{
    return task.ContinueWith(_ => { });
}

faultedTask.SwallowExceptions().Wait();
if (faultedTask.IsFaulted)
{
    // handle exception
}

If your task returns a value, you can represent that in the extensions method and return the actual value if there were no exceptions or the default value if there were:

public static Task<T> SwallowExceptions<T>(this Task<T> task)
{
    return task.ContinueWith(completedTask => 
        completedTask.IsFaulted 
            ? default(T) 
            : completedTask.Result);
}
like image 43
i3arnon Avatar answered Sep 22 '22 20:09

i3arnon