【问题标题】:Correct way to stop ReadAsStreamAsync停止 ReadAsStreamAsync 的正确方法
【发布时间】:2023-03-28 07:52:01
【问题描述】:

我的代码如下:

_req = new HttpRequestMessage(HttpMethod.Get, _uri);
_response = await _httpClient.SendAsync(_req, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);

var rawResponse = new byte[_maxContentLength];

using (var responseStream = await _response.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
    int read;
    int offset = 0;

    do
    {
        read = await responseStream.ReadAsync(rawResponse, 0, rawResponse.Length).ConfigureAwait(false);
        html += Encoding.UTF8.GetString(rawResponse, 0, read);
        offset += read;

        if (offset > _maxContentLength)
        {
            return Error("Too big");
        }

    } while (read != 0);
}

“return Error()”是否足以释放流和套接字以获取下一个 url?

//编辑: 对于某些页面await responseStream.ReadAsync 挂起并且永远不会返回

【问题讨论】:

  • 您还需要在响应周围加上 using()。这应该可以释放所有资源。
  • _response 被放置在另一个地方,因为它是类范围的变量

标签: c# asynchronous httprequest async-await dotnet-httpclient


【解决方案1】:

尝试创建一个 CancellationTokenSource 并在您想要停止时调用 Cancel。我假设您在开始时无法读取 Content-Length 标头,因为响应是块编码的?

【讨论】:

  • Content-Length 不是解决方案,因为 _response = await _httpClient.SendAsync(_req, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);处理后总是下载所有内容,我不知道有什么方法可以在不下载的情况下关闭连接
  • 问题是why don't you check the value of Content-Length before you start downloading?此外 - 如果您不对响应对象调用 HttpResponseMessage.Dispose ,则在垃圾收集器运行之前不会释放连接和流。
  • 我正在检查但不是针对它存在的每个站点
  • @ekapek Content-Length 始终存在,除非发件人使用分块编码。
  • @PanagiotisKanavos 连接的管理完全独立于 HttpResponseMessage 的生命周期。当您处理 HttpClient 实例时,它会尝试关闭连接,但这完全没有必要,因为 ServiceConnectionPoint 类管理连接池。
猜你喜欢
  • 2010-09-26
  • 1970-01-01
  • 2013-11-24
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
相关资源
最近更新 更多