问题
我在WebAPI中使用DelegatingHandler来读取响应内容并将其审核到数据库。
当代码到达.ReadAsStringAsync()时,它似乎会锁定并阻止其他请求完成。我只知道这一点,因为当我删除违规行时,它完美无缺。
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new ResourceAuditHandler());
}
public class ResourceAuditHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
string content = "";
if (response.Content != null)
{
//THIS SEEMS TO CREATE DEADLOCK!
content = await response.Content.ReadAsStringAsync();
}
AuditResponseToDatabase(content);
return response;
}
}
可能的原因
我已经读过,当应用程序的两个位试图从同一个请求/响应(DelegatingHandler和Controller / ModelBinder)读取内容时会发生这种情况......或者更具体地说,当一个人试图读取时异步响应的.Result ,但另一个实例已经读取了结果/响应流,然后为空。
我的第一个请求,命中一个简单的控制器,但第二个请求,命中一个控制器,该控制器的属性检查Action参数“id”以检查它是否为空。我已经读过,当DelegatingHandler和控制器ModelBinder都试图从响应中读取时,你会遇到死锁。
替代方法(也失败)
我也尝试过使用 .ReadAsByteArrayAsync()的其他方法(如其他SO问题所示),但这似乎仍然锁定。我知道这种方法不使用 .Result 方法并直接从响应流中读取它(不知何故)。
var response = await base.SendAsync(request, cancellationToken);
string content= "";
if (response.Content != null)
{
var bytes = await response.Content.ReadAsByteArrayAsync();
responseContent = Encoding.UTF8.GetString(bytes);
}
AuditResponseToDatabase(content);
请帮忙!
答案 0 :(得分:1)
async/await
。换句话说,不要阻止async
代码。您应该做的另一件事是使用.ConfigureAwait(false)
:
var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
string content = "";
if (response.Content != null)
{
content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
您可以在此link
找到更多信息如果以上都不奏效,请提供完整的示例,好吗?
希望这有帮助!