要僅壓縮/縮小大於給定大小限制的WebAPI響應,我必須找出要返回的內容的大小。但是,以下行:在DelegatingHandler中調用LoadIntoBufferAsync時出現死鎖
response.Content.LoadIntoBufferAsync()
似乎在API響應週期後面導致死鎖。大小被正確確定,並且處理程序執行正常,但之後該請求將永久掛起。
這是我的DelegatingHandler的SendAsync方法。
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken).ContinueWith(
task =>
{
HttpResponseMessage response = task.Result;
if (response.RequestMessage != null && response.RequestMessage.Headers.AcceptEncoding != null && response.RequestMessage.Headers.AcceptEncoding.Count > 0)
{
if (response.Content != null)
{
response.Content.LoadIntoBufferAsync(); // when I remove this line the request finishes, but then ContentLength = 0
if (response.Content.Headers.ContentLength > 4000)
{
string encodingType = GetEncodingType(response.RequestMessage.Headers.AcceptEncoding); // use deflate if possible
if (encodingType == "deflate" || encodingType == "gzip")
{
response.Content = new CompressedContent(response.Content, encodingType);
}
}
}
}
return response;
}, cancellationToken);
}
我嘗試了Wait(..),ConfigureAwait(..)和ContinueWith(..)的不同組合。使用async/await語法,我遇到了同樣的問題。
編輯:壓縮機SerializeToStreamAsync(負責壓縮內容流):
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Stream compressedStream = null;
if (m_EncodingType == "gzip")
{
compressedStream = new GZipStream(stream, CompressionMode.Compress, true);
}
else if (m_EncodingType == "deflate")
{
compressedStream = new DeflateStream(stream, CompressionMode.Compress, true);
}
return m_OriginalContent.CopyToAsync(compressedStream).ContinueWith(task =>
{
if (compressedStream != null)
{
compressedStream.Dispose();
}
});
}
=> Apperently當這之後稱爲管道破裂:
response.Content.LoadIntoBufferAsync()
調用的任一兩個人單獨工作,所以他們必須是讀/寫內容流時遇到的問題。
那麼,目前的變型,絕對是錯誤的* *。任何時候當你看到一個名稱以'Async'結尾的方法,其中的返回值被忽略時,它應該觸發警報響鈴。 –
我認爲問題在於我在CompressedContent類中使用壓縮流重新覆蓋了內容,因此內容變得混亂。 – Philipp