Gerard
Gerard

Reputation: 13397

Awaited task does not handle exception gracefully

I expected that I could use this pattern:

var task = Task.Run(() => Agent.GetUserType(Instance));
await task;
string information = task.GetExceptionOrStatus(); // extension method

When my sql server is not started - just as a testcase - I see that the exception that the WCF service throws, is not handled gracefully by the task, I get:
An exception of type 'System.ServiceModel.FaultException' occurred in Microsoft.Threading.Tasks.dll but was not handled in user code.
I was under the impression that my code would be able to extract the error from the task object.

How should I do it better?

Upvotes: 2

Views: 701

Answers (3)

svick
svick

Reputation: 244757

If you don't want await to throw, you could create a new Task based on the previous Task, that never fails. Something like:

static async Task<T> IgnoreException<T>(this Task<T> task)
{
    try
    {
        return await task;
    }
    catch
    {
        return default(T);
    }
}

Alternative implementation:

static Task<T> IgnoreException<T>(this Task<T> task)
{
    return task.ContinueWith(t => t.Exception == null ? t.Result : default(T));
}

Usage then would look like this:

await task.IgnoreException();
string information = task.GetExceptionOrStatus(); // extension method

Upvotes: 2

Stephen Cleary
Stephen Cleary

Reputation: 456417

await will propagate any exceptions on that task, by design.

var task = Task.Run(() => Agent.GetUserType(Instance));
try
{
  await task;
}
catch (Exception ex)
{
  // TODO
}
string information = task.GetExceptionOrStatus(); // extension method

Upvotes: 6

Adam Modlin
Adam Modlin

Reputation: 3024

You should surround your await task; in a try/catch block. If an Exception occurs, it will throw an AggregateException containing all the exceptions that occurred within your Task.

Upvotes: 1

Related Questions