0

我正在处理 asp.net core 2 上的上传服务 API,由于我正在处理文件,我想知道是否有必要在完成包含文件的对象后实现 IDispose 接口并调用 Dispose() 方法或将其留给 .net 核心框架来调用垃圾收集器。

编辑1:(这是我的代码的一部分)

 public class UploadFileModel
{
    [Required]
    public IFormFile FileBinary { get; set; }

    [Required]
    [MaxLength(50)]
    public string Type { get; set; }
}
4

2 回答 2

0

这里有一个关于 here 的所有权的相当大的IDisposable 讨论

普遍的共识是你不应该处理IDisposable你没有创建的。

显然,如果您选择将IFormFile的流内容复制到另一个流,那么您当然有责任处理新的Stream(例如 MemoryStream),因为您创建了它。

因此,假设您的控制器接受以下对象进行模型绑定:

public class MyRequestObject
{
    public IFormFile ChosenFile { get; set; }
}

下面using确保新MemoryStream的被处理,但不是来自的原始流IFormFile

public async Task<IActionResult> Index(MyRequestObject requestModel)
{
    using (var myMemoryStream = new MemoryStream) 
    {
        requestModel.ChosenFile.CopyToAsync(myMemoryStream);

        // Use new memory stream (myMemoryStream) here...
    }
}

或者,如果你在知道你已经完成它之后调用Dispose()该方法返回的那个Stream,那么它不会导致问题。如果需要,您可以将其包装在 using 语句中......IFormFileOpenReadStream()

这是由另一个IDisposable.Dispose()最佳实践支持的,即:

如果多次调用对象的 Dispose 方法,则对象必须忽略第一次调用之后的所有调用。如果多次调用其 Dispose 方法,则该对象不得引发异常。

因此,如果您愿意,可以在控制器操作中安全地执行此操作:

public async Task<IActionResult> Index(MyRequestObject requestModel)
{
    using (var fileStream = requestModel.ChosenFile.OpenReadStream()) 
    {            
        // Make use of fileStream...

    } // using calls Dispose()
}

然而Stream,返回的实现是类型ReferenceReadStreamwho's 的Dispose方法不做任何事情,即它本质上没有实现,它实际上并没有处理 . 中的底层StreamIFormFile尽管这可能会改变。

在任何情况下,您当然不需要IDisposable自己实现。

于 2022-03-06T00:42:01.427 回答
-1

我会说不,没有必要这样做。通常 microsoftIDisposable在需要处理的类型上实现,例如DbContextfrom ef-core。的实现包含一个流,该流在调用时IFormFile被放置在finally 语句中

Task CopyToAsync(Stream target, CancellationToken cancellationToken = default (CancellationToken));

您只需要确保关闭您传入的流。

于 2018-08-02T11:15:13.157 回答