销毁 Web 服务代理类?

6
当您在ASP.Net框架中创建和使用Web服务代理类时,该类最终继承自Component类,该类实现了IDisposable接口。
我从来没有看到过任何在线示例中有人处理Web代理类的释放,但是我想知道是否真的需要这样做。当我只调用一个方法时,通常会将其包装在using语句中,但如果我需要在页面中多次调用它,则可能会重复使用同一实例,我只是想知道不进行处理的后果是什么。
4个回答

8

你需要处理实现 IDisposable 的所有内容。

IDisposable 的实现表示对象持有垃圾回收器本质上不跟踪的“某些东西”-可能是连接,可能是文件,可能是其他句柄-或可能什么都没有,这并不重要。你不应该关注实现细节,因为它们可能会改变。

类可能真正使用非托管资源,也可能没有终结器。这并不重要;如果类实现了 IDisposable,那么它要求你在完成后进行 Dispose。即使 Dispose 方法什么也不做,你也永远不知道什么时候有人会用一个真正需要被释放的子类替换对该类的引用。


6
简短回答是,使用Web服务代理类时,应关闭它们而不是处理它们。
几乎在每种情况下,您都应该处理实现IDisposable的内容。但是,Web服务代理类是一种特殊情况。对于这些类以及从System.ServiceModel.ClientBase继承的所有类,最佳做法是不调用dispose而直接调用Close方法。
使用反射器,您可以看到ClientBase的Dispose方法只是调用Close。因此,如果没有异常,Dispose和Close将执行相同的操作。但是,如果存在异常,则会有不同的行为。
由于Close方法可能会抛出异常,因此应直接调用它并捕获其异常。如果调用Dispose方法,则也应该捕获异常,但您的代码将更难理解。
这也意味着您应该避免在using语句中声明代理。在这种情况下,如果using块中抛出异常,它将被掩盖。由using块自动生成的Dispose调用将被调用,因为它在finally块中。从Dispose中的Close抛出的异常将掩盖先前抛出的任何异常。
要查看更详细的说明,请阅读MSDNCoding Up StyleBlogginAbout.NetStackOverflow上的文章。

关于为什么要这样实现的背景故事,请查看MSDN论坛上的此帖。


1
请注意,这些链接是特定于WCF服务引用,而不是.NET 2.0 Web引用。创建代理的方式会有所不同。 - TrueWill

3
有时候Dispose()只是一个虚拟方法(从基类继承而来),但调用它仍然是一个好习惯,以便为将来的更改做好准备。
WebService/WCF代理确实持有连接,因此调用Dispose()或Close()肯定是一个好主意。在using块内这样做当然更可取,因为它是异常安全的。
但在您的情况下(在页面上使用代理的多个方法),使用多个using块可能会影响性能。可以用一个在页面周期后发生的事件替换using块,并在其中调用Close()。我不确定ASP.NET最佳实践是什么,但我会使用OnPreRender或OnPageUnload之类的东西。
这里你会失去异常安全性,但这不是一个根本性的问题,GC会解决这个问题。

1

个人认为,没有什么比处理Web服务代理类更好的了。

大多数代理都是:

  • 无状态的,因此使用一个实例或多个实例进行调用并没有任何区别
  • 间歇性的,意味着它们在所有响应被处理完毕后立即关闭连接

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