要仅压缩/缩小大于给定大小限制的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