Нужно ли утилизировать объекты, содержащие IFormFile (двоичный файл) asp.net core 2
Я работаю над API службы загрузки на asp.net core 2, и поскольку я работаю с файлами, мне интересно, нужно ли реализовывать интерфейс IDispose и вызывать метод Dispose() после того, как я закончу с объектом, который содержит файл или оставьте это.NET Core Framework для вызова сборщика мусора.
Редактировать 1: (вот часть моего кода)
public class UploadFileModel
{
[Required]
public IFormFile FileBinary { get; set; }
[Required]
[MaxLength(50)]
public string Type { get; set; }
}
2 ответа
Я бы сказал, нет, в этом нет необходимости. Обычно майкрософт реализует IDisposable
на типы, которые должны быть расположены как DbContext
от ef-core. Реализация IFormFile
содержит поток, который располагается в операторе finally при вызове
Task CopyToAsync(Stream target, CancellationToken cancellationToken = default (CancellationToken));
Вам нужно только убедиться, что вы закрываете поток, который вы передаете.
Здесь идет довольно обширная дискуссия о владении здесь.
Общий консенсус заключается в том, что вы не должны избавляться от того, что вы не создавали.
Очевидно, что если вы решите скопировать содержимое потока 's в другой поток, тогда, конечно, вы несете ответственность за удаление нового (например, MemoryStream), потому что вы его создали.
Итак, предположим, что ваш контроллер принимает следующий объект для привязки модели:
public class MyRequestObject
{
public IFormFile ChosenFile { get; set; }
}
Ниже
using
обеспечивает новый
MemoryStream
удаляется, но не исходный поток из:
public async Task<IActionResult> Index(MyRequestObject requestModel)
{
using (var myMemoryStream = new MemoryStream)
{
requestModel.ChosenFile.CopyToAsync(myMemoryStream);
// Use new memory stream (myMemoryStream) here...
}
}
В качестве альтернативы, если вы позвоните
Dispose()
на том, что возвращается
OpenReadStream()
метод после того, как вы знаете, что сделали с ним, тогда это не вызовет проблем. Вы можете обернуть это в оператор using, если хотите...
Это подкрепляется другой передовой практикой IDisposable.Dispose() , а именно:
Если метод Dispose объекта вызывается более одного раза, объект должен игнорировать все вызовы после первого. Объект не должен вызывать исключение, если его метод Dispose вызывается несколько раз.
Таким образом, вы можете безопасно сделать это в своем действии контроллера, если хотите:
public async Task<IActionResult> Index(MyRequestObject requestModel)
{
using (var fileStream = requestModel.ChosenFile.OpenReadStream())
{
// Make use of fileStream...
} // using calls Dispose()
}
Однако возвращаемая реализация имеет тип
ReferenceReadStream
кто
Dispose
метод ничего не делает, IE по сути не имеет реализации и фактически не избавляется от базового
Stream
в
IFormFile
, хотя, возможно, это может измениться.
Вам, конечно, не нужно реализовывать
IDisposable
свое в любом случае.