Нужно ли утилизировать объекты, содержащие 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свое в любом случае.

Другие вопросы по тегам