Here's my async method for communicating with server:
public static Task<bool> ValidateEmail(string email)
{
var url = ServerBase + Resources + Authorization + "check_existence";
var queryString = SerializationHelper.CreateQueryString(new Dictionary<object, object> {{"email", email}});
try
{
return
HttpHelper.PostAsync(url, queryString, null).ContinueWith(
json => SerializationHelper.DeserializeValidationResponse(json.Result));
} catch (Exception e)
{
return TaskErrorHelper.Error<bool>(e);
}
}
An exception thrown while serializing server response (from DeserializeValidationResponse
method) isn't caught. What am I doing wrong?
UPD: TaskErrorHelper.Error
code:
internal static Task<T> Error<T>(Exception e)
{
var tcs = new TaskCompletionSource<T>();
tcs.SetException(e);
return tcs.Task;
}
You're not doing anything wrong. What's wrong is your belief that the exception handler has anything to do with the continuation. Let's leave continuations out of it for a moment and just consider this:
Is it your belief that the catch handler ought to catch the exception thrown by
action()
just becauseaction
happened to be created on a stack frame that had a handler?That's not how exceptions work.
Your situation is just a more complicated version of this little program. The continuation delegate isn't run until long after the exception handler is gone. Heck, the continuation might not even be run on the same thread!
So how do you get the exception? If the continuation throws an exception then it will be caught automatically and the exception will be stored in the task. You can then pull it out of the task.
Or, you could rewrite your program to put a copy of the handler in the continuation:
Or, if you use
async-await
in C# 5, you do get some joy:Now the compiler rewrites your code so that it does what you want. The benefit of
await
is that you don't have to write any of this crazy "continue with" logic; the compiler does it for you.