Async Await or ContinueWith

So what’s the difference with these 2 code snippets?

var result = await subscriber.RunAsync((T)messagePacket.Body, cancellationToken);

 

await subscriber.RunAsync((T)messagePacket.Body, cancellationToken) .ContinueWith(anticedant => { //do something });

Well not much really, except for the error handling. What to do with those pesky exceptions. Especially since we are handing in a cancelation token. If the operation is canceled then an exception will be thrown. In the first instance the await keyword is kind of hiding the task that the Async operation returns. It will catch the exception and in this instance re-throw a new exception. You can choose how to handle it either wrapping the call or allowing it to percolate up the call stack.

In the second snippet we can do something without a new exception being thrown. We can look at the task that is returned and do something depending on the state of the task.

await subscriber.RunAsync((T)messagePacket.Body, cancellationToken)
    .ContinueWith(anticedant =>
    {
       switch (anticedant.Status)
       {
           case TaskStatus.RanToCompletion:
               //do something ... or nothing
               break;
           case TaskStatus.Faulted:
               subscriber.Abort();
               Trace.WriteLine("Request failed");
               break;
           case TaskStatus.Canceled:
               subscriber.Abort();
               Trace.WriteLine("This task timed out"); 
               break;
    }
    });

We lose a little of the readability of the Async await keyword paring and of course we could always wrap the first method in a try catch block and handle the second exception thrown, but I was taught that throwing exceptions is bad and expensive and for me I can understand what’s going on so I am going to stick with ContinueWith when I need to handle a cancelled or timed out request.

Advertisements