当您在ASP.Net框架中创建和使用Web服务代理类时,该类最终继承自Component,它实现了IDisposable。
我从未在网上看到一个人们处理Web代理类的例子,但是想知道它是否真的需要完成。当我只调用一个方法时,我通常将它包装在using语句中,但如果我需要在整个页面中多次调用它,我可能最终会使用相同的实例,并且只是想知道没有处理的后果是什么它
答案 0 :(得分:8)
您需要处理实现IDisposable
的所有。
IDisposable
的实现表示该对象保留了垃圾收集器本身没有跟踪的某些 - 可能是一个连接,可能是一个文件,可能是其他一些句柄 - 或者可能什么都不是,这并不重要。您不应该关注实现细节,因为这些细节可能会发生变化。
该类可能会也可能不会真正使用非托管资源。它可能有也可能没有终结器。它没什么区别;如果该类实现IDisposable
,那么当您完成时它会要求您Dispose
。即使Dispose
方法什么都不做,你也不会知道有人会在引用真正 需要处理的子类的情况下替换对该类的引用。
答案 1 :(得分:6)
简短的回答是,对于Web服务代理类,您应该关闭它们而不是处理它们。
几乎在每种情况下,您都应该处理实现IDisposable的内容。但是,Web服务代理类是一种特殊情况。对于这些类以及从System.ServiceModel.ClientBase
继承的所有类,最佳做法是不调用dispose,而是直接调用Close方法。
使用反射器,您可以看到Dispose
的{{1}}方法只是调用ClientBase
。因此,如果没有例外,Close
和Dispose
将执行相同的操作。但是,如果存在异常,则会有不同的行为。
因为Close
方法可以抛出异常,所以应该直接调用它并捕获它的异常。如果你调用Close
方法,你也应该捕获异常,但你的代码将更难理解。
这也意味着您应该避免将代理声明放在Dispose
语句中。在这种情况下,如果在using
块中抛出异常,它将被遮挡。 using
块自动生成的Dispose
调用将被调用,因为它位于using
块中。 finally
中Close
抛出的异常会掩盖之前抛出的异常。
要查看更详细的说明,请阅读MSDN,Coding Up Style,BlogginAbout.Net和StackOverflow上的这些文章。
关于为什么以这种方式实现它的背景故事,请查看MSDN forums上的这个帖子。
答案 2 :(得分:3)
有时Dispose()只是一个虚拟(从基类继承),但是调用它仍然是一个很好的做法,以便将来更改安全。
WebService / WCF代理 持有连接,因此调用Dispose()或Close()当然是个好主意。在使用块内部这样做当然是优选的,因为它是异常安全的。
但是在您的情况下(在您的页面上使用多个方法中的代理),使用多个使用块可能会受到性能影响。可以在页面循环后期的事件中使用调用Close()替换使用块。我不确定这里的ASP.NET最佳实践,但我会使用OnPreRender或OnPageUnload等。
你会在这里放松异常安全,但这不是一个根本问题,GC会解决这个问题。
答案 3 :(得分:1)
大多数代理是: