【问题标题】:Returning a file in asp net core 3.0 is leaking memory在 asp net core 3.0 中返回文件正在泄漏内存
【发布时间】:2020-02-09 23:48:01
【问题描述】:

我有这个方法。

[HttpGet("view/{fileId}/{width}/{height}/{name}")]
public async Task<FileStreamResult> View(Guid fileId, int width, int height, string name)
{
    var fileInfo = await _fileViewer.GetImageInfo(fileId, width, height);
    FileStream f = new FileStream(fileInfo.FilePath, FileMode.Open);
    return File(f, fileInfo.MimeType);
}

这只是将一个调整后的图像返回给浏览器。有用。但据我所知,它会泄漏内存。

FileStream f 永远不会被释放。

我可以看到我的服务器内存正在慢慢用完。

如果我在其中添加using 语句,我会收到流已关闭的错误,即在文件返回给用户之前使用语句关闭。

这应该如何正确完成?

更新 1。 这个:

using (FileStream f = new FileStream(fileInfo.FilePath, FileMode.Open))
{
    return File(f, fileInfo.MimeType);
}

产量

System.ObjectDisposedException:无法访问已处置的对象。 对象名称:'无法访问已关闭的文件。'。

【问题讨论】:

  • 能否包含您为using 语句实现的代码?显然,正确的答案是显式调用Dispose() 或将FileStream 包装在using 语句中,但我们需要评估为什么您的using 语句不起作用。
  • 您可以尝试将流复制到字节数组并使用 File 方法的另一个重载。在这种情况下,您可以在请求结束之前关闭流。
  • @pwrigshihanomoronimo 我试过了,它也可以,但我更愿意将文件流式传输给用户。我可能是错的,但我认为这样它不会被加载到 RAM 中。
  • 如果您的假设是正确的,那么在他们的应用程序中使用此构造的每个人都会遇到内存泄漏。既然不是,我想你会发现不是这种方法导致内存泄漏。
  • This 是您传递给 File 方法的 Stream 被清理的地方。

标签: c# asp.net-core asp.net-core-3.0


【解决方案1】:

我建议您使用 Asp.net Core 文件提供程序,而不是使用 system.IO 手动读取文件。 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-3.1

但是如果你不想使用依赖注入并将 fileProvider 注入到你的控制器,这个技巧应该对你有用:

var fileInfo = await _fileViewer.GetImageInfo(fileId, width, height);
var fileName = Path.GetFileName(fileInfo.FilePath);
IFileProvider x = new PhysicalFileProvider(Path.GetDirectoryName(fileInfo.FilePath));
IFileInfo fi =  x.GetFileInfo(fileName);
 // you can use your mime type as second argumant. (fileInfo.MimeType)
return File(fi.CreateReadStream(), MediaTypeNames.Application.Octet , fileName);

【讨论】:

    猜你喜欢
    • 2017-05-11
    • 2023-01-30
    • 2021-07-19
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    相关资源
    最近更新 更多