谁拥有.NET包流(如TextWriter的)? [英] Who owns wrapped streams (e.g. TextWriter) in .NET?

查看:115
本文介绍了谁拥有.NET包流(如TextWriter的)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了一个错误的ObjectDisposedException:无法访问已关闭的流

  [的ObjectDisposedException:无法访问已关闭的流]
    System.IO.MemoryStream.Write(字节[]缓冲区的Int32偏移的Int32计数)10184402
    System.Security.Cryptography.CryptoStream.FlushFinalBlock()+114
    System.Security.Cryptography.CryptoStream.Dispose(布尔处置)+48
 

使用code以下的格式时:

 使用(VAR流=新的MemoryStream())
{
    使用(VAR hashStream =新CryptoStream的(流,
                                    新SHA256Managed(),CryptoStreamMode.Write))
    使用(VAR作家=新的TextWriter(hashStream))
    {
        writer.Write(东西);
    }
    // ^  - 异常发生在hashStream处置
    //虽然我天真地认为TextWriter.Dispose不会碰
    //底层流(S)。
    返回stream.ToArray();
}
 

所以异常造成的,因为在的TextWriter的处置,处置的流(hashStream)的包裹。我的问题是这样的:

  1. 这是否约定应用(使用默认构造函数/参数)来的所有的流中的.NET?

    时有佳能讨论这个资源使用模式?例如,可以将其假定的CryptoStream将已关闭的MemoryStream?我知道答案,并且有是专门关于这个,但我想它的设计方针,如果有这样的条款处理。

  2. 在哪里这样的行为记录?

    我找不到在 的TextWriter(流) 或<一href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream.cryptostream.aspx"相对=nofollow> 的CryptoStream 构造 - 当然我只是希望在错误的位置。 (更新:显然我在读失败,正如刚才itsme86此的的记录在TextWriter的构造函数文档)

  3. 什么是写这样的code普遍接受的方法?

    也就是说,底层流需要被读取(在所有行动结束,因而仍处于打开状态),而所有的嵌套流应关闭/刷新的完全的 - 一个简单的<一个href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream.flush%28v=vs.110%29.aspx"相对=nofollow> CryptoStream.Flush 是不充分的,例如

解决方案

使用语句的 C#规格并寻找周围的一些实施流(内存,文件等)我看到的默认行为是处置底层打电话时流的Dispose()。 有一定的溪流在这里你可以明确说明你不想处理底层流的,像 DeflateStream

 公共DeflateStream(流流,COM pressionLevel COM pressionLevel,布尔leaveOpen)
 

  

leaveOpen类型:System.Boolean离开流对象公开   后处置DeflateStream对象;否则为false。

当然,你可能会解决的处置不使用using语句,或者实施 WrapperStream 类,包装你的流,不配置底层流

I've recently encountered an error "ObjectDisposedException: Cannot access a closed Stream"

[ObjectDisposedException: Cannot access a closed Stream.]
    System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +10184402
    System.Security.Cryptography.CryptoStream.FlushFinalBlock() +114
    System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing) +48

when using code following the format:

using (var stream = new MemoryStream())
{
    using (var hashStream = new CryptoStream(stream,
                                    new SHA256Managed(), CryptoStreamMode.Write))
    using (var writer = new TextWriter(hashStream))
    {
        writer.Write("something");
    }
    // ^-- Exception occurs on hashStream Dispose
    //     While naively I assumed that TextWriter.Dispose wouldn't touch the
    //     underlying stream(s).
    return stream.ToArray();
}

So the exception is caused because the Dispose of the TextWriter Disposes the Stream (hashStream) that is wrapped. My questions are thus:

  1. Does this convention applied (with default constructors/arguments) to all stream in .NET?

    Is there canon discussing this resource usage pattern? For instance, can it be assumed that the CryptoStream would have closed the MemoryStream? I know the answer, and there are other questions specifically about this, but I would like it addressed in terms of a design guideline if there is such.

  2. Where is such behavior documented?

    I can't find "ownerships" discussed in the TextWriter(stream) or CryptoStream constructors - surely I am just looking at the wrong location. (Update: apparently I fail at reading, as pointed out by itsme86 this is documented in the TextWriter constructor documentation.)

  3. What is the universal accepted method to write such code?

    That is, the underlying stream needs to be read (at the end of all operations, and thus still open) while all the nested streams should be closed/flushed completely - a simple CryptoStream.Flush is not sufficient, for instance.

解决方案

After reading the using statement C# spec and looking around some of the implemented streams (memory, file, etc..) i see that the default behavior is to dispose the underlying streams when calling Dispose(). There are certain streams where you can explicitly state that you dont want to dispose of the underlying stream, like in DeflateStream:

public DeflateStream(Stream stream, CompressionLevel compressionLevel, bool leaveOpen)

leaveOpen Type: System.Boolean true to leave the stream object open after disposing the DeflateStream object; otherwise, false.

Of course, you might work around the disposal by not using the using statement, or perhaps implementing a WrapperStream class which wrap your stream and doesn't dispose the underlying stream.

这篇关于谁拥有.NET包流(如TextWriter的)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆