awh*_*112 5 .net c# memory asp.net memory-leaks
我正在使用一个控制台应用程序,该应用程序将视频数据的端点列表包含在内,发出一个HTTP请求,并将结果保存到文件中。这些是相对较小的视频。由于我无法控制的问题,其中一个视频非常大(145分钟而不是几秒钟)。
我看到的问题是,在调用该请求后,我的内存使用量猛增至〜1 GB,最终出现“任务已取消”错误(可能是因为客户端超时)。很好,我不想要这部影片,但有关的是,无论我做什么,我分配的内存都保持很高。我希望能够释放内存。似乎与此有关的是,任务管理器显示〜14 MB的内存使用量,然后此后不断增加。在VS调试器中,我只是看到一个峰值。
我尝试将所有内容都放入一条using语句中,重新初始化HttpClienton异常,但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)
    {
    }
}
看一下我的调试器输出:
我想我对所看到的有一些疑问:
在此先感谢您的帮助!
除了 @spender 的答案(这是正确的)之外,您还需要确保在完成后处理响应。您可以在“使用 HttpClient 高效地流式传输大型 HTTP 响应”一文中找到有关此内容的更多信息。
这是一个代码示例:
using (HttpClient client = new HttpClient())
{
    const string url = "https://github.com/tugberkugurlu/ASPNETWebAPISamples/archive/master.zip";
    using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
    using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync())
    {
        string fileToWriteTo = Path.GetTempFileName();
        using (Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create))
        {
            await streamToReadFrom.CopyToAsync(streamToWriteTo);
        }
    }
}
您还需要考虑到不应HttpClient为每个操作创建一个实例。HttpClientFactory是一种非常有组织的方式,可确保您以最高效的方式在应用程序中安全地传输 HttpClient。
如果使用HttpClient.SendAsync(HttpRequestMessage, HttpCompletionOption)而不是GetAsync,则可以提供HttpCompletionOption.ResponseHeadersRead,(而不是默认值ResponseContentRead)。这意味着响应流将在响应正文下载之前(而不是在下载之后)交还给您,并且所需的缓冲区要少得多。
| 归档时间: | 
 | 
| 查看次数: | 1164 次 | 
| 最近记录: |