我正在开发一个控制台应用程序,它获取视频数据的端点列表,发出 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)
{
}
}
下面是我的调试器输出:
我想我对我所看到的有几个问题:
- 我看到的内存使用量真的是个问题吗?
- 有什么方法可以释放由大型 HTTP 请求分配的内存?
- 有什么方法可以在调用和分配内存之前查看请求的内容长度?到目前为止,我还没有找到在实际内存分配之前找出的方法。
预先感谢您的帮助!
最佳答案
如果您使用 HttpClient.SendAsync(HttpRequestMessage, HttpCompletionOption)
您可以提供 HttpCompletionOption.ResponseHeadersRead
而不是 GetAsync
, (相对于默认的 ResponseContentRead
)。这意味着响应流将在响应主体下载之前(而不是下载之后)返回给您,并且需要的缓冲区要少得多。
关于c# - HttpClient 内存使用量激增且响应较大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44310239/