c# - HttpClient 内存使用量激增且响应较大

标签 c# asp.net .net memory memory-leaks

我正在开发一个控制台应用程序,它获取视频数据的端点列表,发出 HTTP 请求,并将结果保存到文件中。这些是相对较小的视频。由于我无法控制的问题,其中一个视频非常很大(145 分钟而不是几秒钟)。

我看到的问题是在调用该请求后我的内存使用量激增至 ~1 GB,并且我最终收到“任务已取消”错误(可能是因为客户端超时)。这很好,我不想要这个视频,但令人担忧的是,无论我做什么,我分配的内存都很高。我希望能够释放内存。任务管理器显示大约 14 MB 的内存使用情况似乎令人担忧,直到这次调用,然后才不断增加。在 VS 调试器中,我只看到一个尖峰。

我尝试将所有内容都放在 using 语句中,重新初始化 HttpClient 异常,手动调用 GC.Collect() 没有运气。我正在使用的代码看起来像这样:

consumer.Received += async (model, ea) =>
{
    InitializeHttpClient(source);
    ...
    foreach(var item in queue)
    {
        await SaveFileFromEndpoint(url, fileName);
        ...
    }
}

和方法:

public void InitializeHttpClient(string source)
{
    ...
    _client = new HttpClient();
    ...
}

public async Task SaveFileFromEndpoint(string endpoint, string fileName)
{
    try
    {
        using (HttpResponseMessage response = await _client.GetAsync(endpoint))
        {
            if (response.IsSuccessStatusCode)
            {
                using(var content = await response.Content.ReadAsStreamAsync())
                using (var fileStream = File.Create($"{fileName}"))
                {
                    await response.Content.CopyToAsync(fileStream);
                }
            }
        }
    }
    catch (Exception ex)
    {

    }
}

下面是我的调试器输出:

memory spike

我想我对我所看到的有几个问题:

  1. 我看到的内存使用量真的是个问题吗?
  2. 有什么方法可以释放由大型 HTTP 请求分配的内存?
  3. 有什么方法可以在调用和分配内存之前查看请求的内容长度?到目前为止,我还没有找到在实际内存分配之前找出的方法。

预先感谢您的帮助!

最佳答案

如果您使用 HttpClient.SendAsync(HttpRequestMessage, HttpCompletionOption)您可以提供 HttpCompletionOption.ResponseHeadersRead 而不是 GetAsync , (相对于默认的 ResponseContentRead)。这意味着响应流将在响应主体下载之前(而不是下载之后)返回给您,并且需要的缓冲区要少得多。

关于c# - HttpClient 内存使用量激增且响应较大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44310239/

相关文章:

c# - Web 服务不再适用于单元测试/客户端代理创建

C# - WHOIS 服务器提前关闭连接或不将整个响应发送到我的套接字?

ASP.NET Web 表单渲染引擎输出控制树?寻找有关渲染逻辑的信息

asp.net - 用于 asp.net 应用程序的可视化并排文本比较工具/例程

.net - 必须在 .net 中一次访问一个静态方法/类/变量吗?

.net - 如何编写 Visual Studio 数据库项目的部署脚本?

c# - 使用 JSON 的 WCF RESTful POST,来自 Windows 应用商店应用

c# - XNA Initialize in Game 只调用一次?

c# - 如何动态更改 td 内容?

.net - 我可以在堆对象而不是变量上设置监视吗?