2011-08-25 45 views
7

我听说,这是必须的Dispose(或关闭),即使为什么很重要处置/关闭WCF客户端代理

  • 你不使用会话
  • 没有一个WCF客户端代理需要确定性清理的非托管资源(例如开放式套接字)

例如,当使用具有默认绑定配置的BasicHttpBinding时,即使在流行的网页中,这也应该没问题吧?

var clt = new MyServiceClient(); 
clt.PlaceOrder(foo); 
// no dispose 

var clt = new ChannelFactory<IOrderService>().CreateChannel(); 
clt.PlaceOrder(foo); 

感谢

+9

我想你_could_让GC为你做,但是这只是不干净的代码。你宣布它,你释放它。基础知识似乎不再被教导。 –

回答

3

创建ChannelFactory &打开它是一个昂贵的操作,如果您关心性能,您应该避免为每次调用执行此操作。

即使使用basicHttpBinding,您的第一个用例也不正确,因为它可能会为每个瞬时创建一个新的channelfactory。 .NET 3.5 SP1引入了一些ChannelFactory缓存,因此在某些情况下您可能会确定。

在你的第二个用例中,如果你缓存并重用了channelfactory,处置并不是真的非常棘手,但请记住你/你的部署人员可以改变绑定@部署时间,并且缺少关闭/处置会产生巨大影响。

总之,关闭/处理总是安全的,这就是为什么MSDN建议这样做的原因。

15

其良好实践关闭的事情(和它们的处置),当你与他们进行。 (即使您通过读/写文件流,您是否还会打开文件流?)另一方面,我可以看到几个原因:

  1. 服务器(可以/将)具有有限的它维护的活动连接的数量。您越早处置您的服务,下一个客户端就有可能使用该插槽。 (如果实际上通过,为什么要等待超时?)
  2. 避免非活动连接的额外开销。这些天被授予的资源是“充足的”,但是最终的成本越低,你的表现越好。
  3. 您可以通过在客户端通过时处置客户端来降低由于超时而导致的错误/异常的风险。
  4. 通过关闭它,当你通过你有效地保持服务器日志清洁。最后,即使客户端没有显示它,服务器也可能由于休眠连接而在日志中显示超时异常,而这些连接在应该发生时没有照顾到。
  5. MSDN says to(请注意WCF客户端对象列表中的第4个项目符号)。

只有几个我能想到的原因。

+0

*关闭*连接不同于连接的*处置*。 –

+3

@Kirk:同意,但也检查以确保没有错误存在,否则应该执行中止。 –

+0

有几个注释 - 文件系统表示非托管资源。问题中的代理人没有。这个问题真的是'为什么',因为它很整洁,或者因为MSDN所说的不是我想要的。你是说Dispose关闭了一个开放的连接(即使是basicHttpBinding),这就是为什么你应该这样做?谢谢 – ConfusedNoob

2

这实际上取决于客户端的类型。例如,如果您编写调用服务的ASP.NET应用程序,那么缓存代理是一个好主意,因为它的创建过程很昂贵。

这就是说,一旦你完成了任何IDisposable资源,你应该对它进行处理,以便被释放的对象有机会释放它所持有的资源,以便它可以从内存中移除。如果一个IDisposable对象有一个Close方法,它应该先被调用。

的这个引人入胜的主题优秀的文章可以在这里找到:http://msdn.microsoft.com/en-us/magazine/bb985010.aspx