【问题标题】:Does a memorystream get disposed when returning from within a using block从 using 块内返回时是否会处理内存流
【发布时间】:2018-10-24 11:00:16
【问题描述】:

在查看 msdn 的 using 语句时,它显示以下内容:

当 IDisposable 对象的生命周期仅限于单个方法时,您应该在 using 语句中声明并实例化它。 using 语句以正确的方式调用对象的 Dispose 方法,并且(当您如前所示使用它时)它还会导致对象本身在调用 Dispose 时立即超出范围。在 using 块中,对象是只读的,不能修改或重新分配。

考虑到 MSDN 提供的信息。 从方法已设为静态的 using 块中返回内存流时。

问:内存流在返回时会被释放,还是会关闭并作为只读内存流继续存在?

下面的代码用于返回内存流。

        public static MemoryStream CreatePermitFileMemoryStream(int encOnlineId)
        {
            var folder = @"path\anotherpath\filelocation";
            try
            {
                using (var zipStream = new MemoryStream())
                {
                    using (var fileStream = new FileStream(@"path\anotherpath\filelocation\file.zip", FileMode.OpenOrCreate))
                    {
                        using (var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create))
                        {
                            foreach (var fileInfo in Directory.EnumerateFileSystemEntries(folder))
                            {
                                if (fileInfo.Contains("file.tmp") || fileInfo.Contains("PERM.TXT"))
                                {
                                    var filename = new FileInfo(fileInfo);
                                    zipArchive.CreateEntryFromFile(fileInfo, filename.Name);
                                }
                            }
                            fileStream.CopyTo(zipStream);
                            zipStream.Position = 0;
                            return zipStream;
                        }
                    }
                }
            }
            finally
            {
                FileUtils.DeleteFile(@"path\anotherpath\filelocation");
            }

        }
        return new MemoryStream();
    }

【问题讨论】:

  • using 块在您调用 return 时退出。所以是的,Dispose 将在 zipStream 上被调用。
  • 您将返回一个已处理的 MemoryStream。所以访问它会抛出异常或返回错误。
  • 如果你真的需要返回一个流(不是字节数组),就不要使用 zipStream 的 using-block。
  • 我也认为它不会执行。但是提供的代码有效..

标签: c# .net


【解决方案1】:

代码可能有效,因为 MemoryStream 上的 Dispose 并没有真正做任何事情(内存由 GC 回收),但我当然不会依赖它总是对所有 .NET 实现都这样做——除非你唯一的功能'正在调用的是GetBuffer(),它保证在关闭流后工作。在这种情况下,删除“使用”可能更安全。 “只读”是指无法将引用重新分配给另一个对象。 顺便说一句,如果您查看https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/IO/MemoryStream.cs Dispose() 中的 cmets,则表明开发人员故意让对象缓冲区在处理后仍然可用,但不能保证从它作为流读取会起作用(并且写入几乎肯定会失败) .

【讨论】:

  • 这回答了我的问题,为什么即使在退出函数(使用 using)后它仍然有效,并且我在另一个调用 ToArray() 的函数中使用它。
【解决方案2】:

答案是。 任何实现 IDisposable 接口的对象都可以在 using 块中使用,以确保在 using 块结束时调用 Dispose()。实际上 using 块充当 try, finally 块,在 finally 块中具有 Dispose()

【讨论】:

    【解决方案3】:

    返回流是可以的。您仍然可以在使用流的地方使用 using 语句:

    using (var permitFileStream = CreatePermitFileMemoryStream(0))
    {
         //Use your stream
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 2011-07-30
      相关资源
      最近更新 更多