.net 不处理MemoryStream/StringReader可以吗?

.net 不处理MemoryStream/StringReader可以吗?,.net,dispose,.net,Dispose,我想创建一个返回XmlReader的方法。根据具体情况,XmlReader可能会收到不同类型的流,StringReader或MemoryStream 通常,我使用using块处理StringReader或MemoryStream,但由于我想返回一个XmlReader,如果我想使用这种设计,我就不能这样做。 我不希望MemoryStream分配大量内存,因此我可以忍受资源释放的轻微延迟 在这种情况下,让GC处理StringReader和MemoryStream的后果可以接受吗 我应该澄清,这是一个

我想创建一个返回XmlReader的方法。根据具体情况,XmlReader可能会收到不同类型的流,StringReader或MemoryStream

通常,我使用using块处理StringReader或MemoryStream,但由于我想返回一个XmlReader,如果我想使用这种设计,我就不能这样做。 我不希望MemoryStream分配大量内存,因此我可以忍受资源释放的轻微延迟

在这种情况下,让GC处理StringReader和MemoryStream的后果可以接受吗

我应该澄清,这是一个实际问题,而不是最佳做法问题。显然,理论要求我应该清理自己的资源分配,但理论也指出我应该更喜欢最简单的设计,以获得最大的可维护性。在某些情况下,违反最佳实践是合理的,我的问题是,这个具体案例是否证明违反最佳实践是合理的

此外,这只是关于StringReader和MemoryStream,而不是一般的流或读取器。
在这种情况下,我为其辩护的理由是,StringReader/MemoryStream的实际创建被很好地封装在返回XmlReader的方法中,因此XmlReader将不会收到具有有限资源的流的控制。

答案:。您应该始终处置可处置资源。在从方法返回流的情况下,处理应该由调用方完成。

如果您为类的显式内部使用分配了资源,那么您的类负责处理该资源。如果您代表调用者分配资源,则调用者有责任管理所请求资源的生存期

虽然CLR最终将释放由任何对象分配的资源,但不确定何时收集(释放)特定对象

因此,如果一个对象使用了一个相对较少的资源,如文件句柄,并且该对象没有被创建它的代码处理掉,那么在垃圾收集器收集持有该句柄的对象之前,该文件句柄将一直不可供系统或其他应用程序使用


在单用户桌面上[机器,您不太可能没有文件句柄,但在繁忙的服务器上,您更可能会接近可用的最大文件句柄数,并且越接近耗尽系统资源,机器就越有可能出现性能下降,因此及时释放资源就更为重要mes是一个更大的问题。

在这种情况下没有什么会受到影响,但在我看来,这仍然是一个非常糟糕的做法。你拥有它们-为什么不正确地做呢?事实上,处理
内存流仍然无法释放等-它仍然受到GC的约束。但是在这里的某个地方有一种明显的代码气味。如果有任何问题,这可能会成为真正的问题不断变化,突然之间,它不是一个
记忆流
,而是其他东西,等等


我们不能让您处理它,但就个人而言:我对使用
非常挑剔。在这种情况下,我不会直接返回流,因为它被包装在XmlReader中。您能解释一下为什么我总是要处理可支配的资源吗?毕竟GC最终会为我这样做,在某些情况下,处理流是不切实际的手动执行。@Holstebroe:您不知道GC最终会为您执行此操作。您可以使用Reflector/ILDASM,并看到某个特定实现没有非托管资源,或者有一个回退终结者来清理它们,但您不能保证所有实现都会如此(包括那些尚不存在的)@Holstebroe,如果抛出异常,您将泄漏非托管句柄。这在ASP.NET应用程序中可能是灾难性的。我总体上理解并尊重这一点,但这是一个实际问题,而不是理论问题。我的意思是,毕竟MemoryStream/StringReader可能只保留了少量内存,我的问题是,这是否证明获取理论上的最佳实践。你能确定在从现在到软件生命周期结束的所有可能情况和环境中,MemoryStream和StringReader只包含少量数据吗?即使你可以,我仍然认为作为一名开发人员,应该尽可能减少应用程序的占用空间尽可能多地对系统进行修改,即使只是一小部分。虽然有点陈旧,但肯定值得一读:Dispose、Finalization和Resource Management-看一看+1:同意,如果你构建了它,你拥有它,它实现了IDisposable,我对处理该对象很虔诚。这是我的责任,我需要一个很好的理由与预期不同。如果使用XslCompiledTransform,通常会导致使用三重嵌套,在简单的情况下,如果您想在读卡器/拖缆的选择上引入一些灵活性,这有时会让人感到恼火,因为在这种情况下,读卡器/拖缆只是包装字符串或字节数组。基于以下原因,我不得不不同意这个答案正如Holsterbroe所提到的,另一种方法是将多个using语句与单个语句一起使用(因此没有额外的作用域大括号)。据我所知,Dispose是为处理操作系统控制的资源而设计的。如果MemoryStream是一个让字节数组像流一样运行的“shiv”,我们知道这一点,那么不处理它们怎么会有代码味道?