tpl

Beware mixing Tasks with async/await

I recently came across an issue within a pipeline of asynchronous method calls where an attempt to deserialize a response from json to a known type may throw an exception, usually when the response is not json. For example, this may be the case when using something like nginx as a proxy for authentication purposes and failed authentication returns a HTML page. A simple reproducible example would be

void Main()
{
    MainAsync().Wait();
}

async Task MainAsync()
{
    var result = await TryDeserializeAsync().ConfigureAwait(false);    
    Console.WriteLine(result);
}

Task<double?> TryDeserializeAsync()
{
    try { 
        return DeserializeAsync(); 
    }
    catch {
        // swallow any exceptions thrown.
    }
    return null;
}

async Task<double?> DeserializeAsync()
{
    await Task.Delay(100);
    throw new Exception("Serialization error");
}

Here we await TryDeserializeAsync() which in turn calls the actual DeserializeAsync() implementation, swallowing any exception that may occur in deserialization and simple returning null. That's the plan anyway.

Read more...