C# HttpClient在收到服务器的响应后无法停止流式传输
我已经为.NET4.5中的C# HttpClient在收到服务器的响应后无法停止流式传输,c#,.net,dotnet-httpclient,C#,.net,Dotnet Httpclient,我已经为.NET4.5中的HttpClient挣扎了一段时间。对于通过分块传输到WebApi端点的大型流式上载,当服务器已使用非成功状态代码(未找到、身份验证、授权、验证错误等)响应mid请求时,它无法停止 通过查看ConnectStream类中的调试器,它知道它从服务器收到了一个非成功状态。从服务器接收到的HTTP状态和数据将被存储,以备以后使用,从那一刻起,它将假装从流中读取,直到最后。从那一刻起,导线上没有写入任何内容,随后通过HttpResponseMessage提供响应。这种无法解释的
HttpClient
挣扎了一段时间。对于通过分块传输到WebApi端点的大型流式上载,当服务器已使用非成功状态代码(未找到、身份验证、授权、验证错误等)响应mid请求时,它无法停止
通过查看ConnectStream
类中的调试器,它知道它从服务器收到了一个非成功状态。从服务器接收到的HTTP状态和数据将被存储,以备以后使用,从那一刻起,它将假装从流中读取,直到最后。从那一刻起,导线上没有写入任何内容,随后通过HttpResponseMessage
提供响应。这种无法解释的行为给我造成了巨大的问题,因为所讨论的流可能相当大。无用的时间被用来阅读流直到结束,加上不正确的上传报告被显示给用户。我停止了web服务器、远程机器,甚至禁用了本地网络接口。HttpClient
不在乎。它继续从提供的流中读取数据
我尝试了HttpCompletionOption。ResponseHeadersRead
和streamdcontent
或PushStreamContent
。同样的行为。我还尝试了HttpWebRequest
,但是它不允许在输出流上写入数据和同时读取输入流。有没有办法阻止客户端在收到服务器的响应后发送或假装发送流?为什么HttpClient
的行为是这样的
var httpClientHandler = new WebRequestHandler
{
AllowAutoRedirect = true,
PreAuthenticate = false,
CookieContainer = cookieContainer,
UseCookies = true,
CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore),
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
var httpClient = new HttpClient(_httpClientHandler)
{
BaseAddress = baseApiUrl,
Timeout = Timeout.InfiniteTimeSpan;
};
httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain", 0.8));
httpClient.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("UTF-8"));
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(appName, appVersion));
var requestContent = new StringContent(serializedRequest, Encoding.UTF8, "application/json");
// the monitored stream is an implementation of the stream that proxies the calls to a classic file stream
// here I monitor the calls made to Read(byte[] buffer, int offset, int count) method
// tried with both CanSeek = false or true - the HttpClient reads the whole stream no matter what.
var streamedContent = new StreamContent(monitoredStream);
streamedContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "upload.bin",
Size = monitoredStream.Length
};
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, relativeUrl)
{
Content = new MultipartFormDataContent
{
requestContent,
streamedContent
}
};
// the Owin middleware could fail checking authentication, an authorization error could occur,
// or the WebApi controller could receive the first part of the multipart data and reject the request
// from the moment data was received from the server, mid-stream, I could safely unplug the network cable
// socket erros are being ignored, actually the underlying socket is no longer used
// the response message contains the status code and data received during the transmission of the request at the end of this call
var httpResponseMessage = await _httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
这是
HttpClient
内部的已确认限制。也许它会在下一个版本中实现,但这不会影响投票支持它。你能展示你的代码吗?