You should use await
.
One of the problems with Result
is that it can cause deadlocks, as I describe on my blog.
The problem with ConfigureAwait
is that by default it will execute the continuation on the thread pool, outside of the HTTP request context.
You can get working solutions with either of these approaches (though as Youssef points out, Result
will still have sub-optimal performance), but why bother? await
does it all for you: no deadlocks, optimal threading, and resuming within the HTTP request context.
var requestBody = await request.Content.ReadAsStringAsync();
Edit for .NET 4.0: First, I strongly recommend upgrading to .NET 4.5. The ASP.NET runtime was enhanced in .NET 4.5 to properly handle Task
-based async
operations. So the code below may or may not work if you install WebAPI into a .NET 4.0 project.
That said, if you want to try properly using the old-school ContinueWith
, something like this should work:
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
var tcs = new TaskCompletionSource<HttpResponseMessage>();
HttpResponseMessage ret;
try
{
... // logic before you need the context
}
catch (Exception ex)
{
tcs.TrySetException(ex);
return tcs.Task;
}
request.Content.ReadAsStringAsync().ContinueWith(t =>
{
if (t.Exception != null)
{
tcs.TrySetException(t.Exception.InnerException);
return;
}
var content = t.Result;
try
{
... // logic after you have the context
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
tcs.TrySetResult(ret);
}, context);
return tcs.Task;
}
And now it becomes clear why await
is so much better...