你应该使用await
.
正如我在博客中所描述的那样,其中一个问题Result
是它可能导致死锁。
问题ConfigureAwait
在于,默认情况下,它将在 HTTP 请求上下文之外的线程池上执行延续。
您可以使用这两种方法中的任何一种获得有效的解决方案(尽管正如 Youssef 指出的那样,Result
性能仍然会次优),但为什么要麻烦呢?await
为您做这一切:没有死锁、优化线程以及在 HTTP 请求上下文中恢复。
var requestBody = await request.Content.ReadAsStringAsync();
.NET 4.0 的编辑:首先,我强烈建议升级到 .NET 4.5。ASP.NET 运行时在 .NET 4.5 中得到了增强,可以正确处理Task
基于 的async
操作。因此,如果您将 WebAPI 安装到 .NET 4.0 项目中,下面的代码可能会或可能不会起作用。
也就是说,如果您想尝试正确使用 old-school ContinueWith
,这样的事情应该可以工作:
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;
}
现在很清楚为什么await
要好得多……