HttpClient无法在接收到服务器响应后停止流传输

4
我在.NET 4.5中使用HttpClient有一段时间了。通过分块传输,向WebApi端点上传大量流时,如果服务器已经在请求中响应了非成功状态码(未找到、身份验证、授权、验证错误等),它会失败而无法停止。
ConnectStream类内部使用调试器查看时,它知道它从服务器接收到了一个非成功的状态。来自服务器的HTTP状态和数据被存储供以后使用,此时它只是假装从流中读取直到结束。从那时起,没有任何东西被写入线路,稍后通过HttpResponseMessage提供响应。这种未解释的行为对我造成了巨大的问题,因为相关流可能很大。浪费了无用的时间读取流直到结束,并且向用户显示了错误的上传报告。我停止了Web服务器、远程机器,甚至禁用了本地网络接口。但是HttpClient并不关心,它继续从提供的流中读取。
我尝试使用HttpCompletionOption.ResponseHeadersReadStreamedContentPushStreamContent,但行为相同。我还尝试使用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);

你能展示一下你的代码吗? - kamil-mrzyglod
1个回答

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接