我使用的是DelegatingHandler中的WebAPI讀取響應內容並將其審計數據庫。
當代碼到達.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和控制器/ ModelBinder的)...或者更具體地說,當您嘗試讀取異步響應的。結果,但另一個實例已經讀取結果/響應流,然後該結果/響應流爲空。
我的第一個請求命中了一個簡單的控制器,但是第二個請求命中了一個控制器,該控制器具有一個檢查Action參數「id」的屬性來檢查它不爲null。我已經讀過,當DelegatingHandler和控制器ModelBinder都試圖從響應中讀取時,你會遇到死鎖。
替代方法(也無法)
我已經使用其他方法(如見於其他SO問題),也嘗試過它採用.ReadAsByteArrayAsync(),但這似乎仍然鎖定。我明白,這種方法不使用。結果的方法,並直接從響應流(以某種方式)讀取它。
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);
請幫忙!
通常情況下,如果你的代碼中的任何地方有'task.Wait()'或'task.Result',那麼就會發生這種情況(在外部調用堆棧上)。是這樣嗎? – Noseratio
@ peter.swallow:你能否創建一個可靠地重現問題的小例子? –