При возврате файла в asp net core 3.0 происходит утечка памяти - PullRequest
4 голосов
/ 08 февраля 2020

У меня есть этот метод.

[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 и получаю сообщение об ошибке, что поток закрывается, ie оператор using закрывается до того, как файл возвращается пользователю.

Как это должно быть сделано правильно?

ОБНОВЛЕНИЕ 1 . Это:

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

приводит к

System.ObjectDisposedException: Невозможно получить доступ к удаленному объекту. Имя объекта: «Невозможно получить доступ к закрытому файлу.».

1 Ответ

1 голос
/ 08 февраля 2020

Я предлагаю вам использовать Asp. net Основные файловые провайдеры вместо ручного чтения файлов с помощью 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);
...