System.ObjectDisposedException: 无法访问已关闭的流

9

这是否意味着流没有被代码(使用using或调用dispose)处置?

即使在此代码外关闭流,仍会发生此异常?


@PhilipDaubmeier - 在其他人之前,你应该将其扩展为一个答案。这是一个有效的问题,可能不会被关闭,并且需要一个答案。你是第一个。赶紧拿下这个功劳吧! - David
1
如果您向我们展示代码,我们可能会指出您问题的源头... - Steve B
有些东西或某人被称为Close()或Dispose()。你对“内部”和“外部”代码的定义是什么?这有什么关系吗? - H H
3个回答

7

所以我的评论将作为答案:是的,流也可以从代码外部关闭,因此请确保检查 System.ObjectDisposedException

有几种情况可能会发生这种情况:例如想象一下与网络连接相关联的流,如果连接突然中断,根据实现方式,可能会关闭流并在访问流时抛出特定的异常。


4
这个异常是否可能在代码外关闭了流?
是的。例如,如果您将一个流包装在另一个流中,并且处理“包装”流,则可能会发生这种情况。许多实现会释放它们正在包装的流。
如果您尝试写入“包装”流,则会收到此错误消息。
还要注意,对于具有Close()方法(例如Stream)的对象,Close和Dispose通常执行相同的功能。关闭流也会使其被处理。

3

如果请求长度磁盘阈值小于您正在尝试通过流上传/处理的文件大小,也会出现此错误。这在您的web.config中定义:

<httpRuntime maxRequestLength="512000" requestLengthDiskThreshold="512000" />

如果你看一下这里第二个参数的解释:

https://msdn.microsoft.com/zh-cn/library/system.web.configuration.httpruntimesection.requestlengthdiskthreshold(v=vs.110).aspx

你会发现它设置了输入流缓冲区阈值(以千字节为单位)。默认值为80KB,因此如果您没有设置该值并且尝试上传大于80KB的文件,例如使用ajax上传,将会抛出System.ObjectDisposedException异常,因为一旦达到阈值限制,流就会关闭。

在我的情况下,我将阈值设置为500MB...


我曾经遇到过这个错误,将 requestLengthDiskThreshold 更改为与 maxRequestLength 相同后问题得以解决,但似乎不应该需要这样做?据我所知,requestLengthDiskThreshold 只是文件在被缓冲到磁盘之前可以达到的最大大小,但是这种缓冲应该是透明的。难道 .NET 不应该从代码的角度来看为我们隐藏它吗?对于我们的代码而言,这只是一个流,我们的代码并不关心它是被流式传输到磁盘还是内存中,并且这个要求可能会随着时间的推移而发生变化... - tomRedox
在我们的系统中,有数十个客户端都使用500MB的RAM(这是可能会导致IIS很快耗尽RAM的情况)。只是为了明确,我并不是说你的答案是错误的,只是似乎在这个框架中有些不太对劲。 - tomRedox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接