C# 为什么处置/关闭WCF客户端代理很重要

C# 为什么处置/关闭WCF客户端代理很重要,c#,.net,wcf,web-services,C#,.net,Wcf,Web Services,我听说处置(或关闭)WCF客户端代理非常重要,即使在 你没有使用会话 没有需要确定性清理的非托管资源(例如,开放套接字) 例如,当使用带有默认绑定配置的BasicHttpBinding时,即使在流行的web页面中也可以,对吗 var clt = new MyServiceClient(); clt.PlaceOrder(foo); // no dispose 或 var clt=newchannelfactory().CreateChannel(); clt.PlaceOrder(foo)

我听说处置(或关闭)WCF客户端代理非常重要,即使在

  • 你没有使用会话
  • 没有需要确定性清理的非托管资源(例如,开放套接字)
例如,当使用带有默认绑定配置的BasicHttpBinding时,即使在流行的web页面中也可以,对吗

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

var clt=newchannelfactory().CreateChannel();
clt.PlaceOrder(foo);
谢谢

当你处理完东西后,关闭(并处理)它们是一种很好的做法。(即使您正在读/写文件流,您是否会让文件流保持打开状态?)

  • 服务器(可以/将要)保持的活动连接数量有限。您越早处置服务,下一个客户端就越早可以使用该插槽。(如果你真的完成了,为什么还要等待超时?)
  • 避免非活动连接的额外开销。当然,现在的资源是“充足”的,但开销越小,最终的表现就越好
  • 通过在客户端完成时处理客户端,可以降低由于超时而导致错误/异常的风险
  • 通过在完成时关闭它,可以有效地保持服务器日志的干净。最后,即使客户端没有显示,服务器也可能会因为休眠连接而导致日志中出现超时异常,而这些连接在本应处理的时候没有得到处理
  • (请注意WCF客户端对象列表中的第四个项目符号)

  • 这只是我脑海中能想到的几个原因。

    创建一个ChannelFactory&打开它是一项昂贵的操作,如果你关心性能,你应该避免每次通话都这么做

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

    在您的第二个用例中,如果缓存并重用channelfactory,那么处理并不是非常必要,但请记住,您/您的部署人员可以在部署时更改绑定,而缺少关闭/处理可能会产生巨大的影响


    总之,关闭/处置总是安全的,这就是MSDN建议这样做的原因

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

    这就是说,一旦您处理完任何IDisposable资源,您应该对其进行处置,以便被处置的对象有机会释放它所持有的资源,从而可以将其从内存中删除。如果IDisposable对象具有Close方法,则应首先调用它


    在这里可以找到一篇关于这个迷人主题的优秀文章:

    我想你可以让GC为你做这件事,但这不是干净的代码。你申报它,你释放它。似乎不再教授的基础知识。关闭连接与处理连接不同。@Kirk:同意,但还要检查以确保没有错误,否则应执行中止。注意事项-文件系统代表非托管资源。问题中的代理没有。问题真的是“为什么”,因为它很整洁,或者因为MSDN这么说,这不是我想要的。您是说Dispose关闭了一个打开的连接(即使对于basicHttpBinding也是如此),这就是您应该这样做的原因吗?thanks@ConfusedNoob:文件处理是一种类比,而不是比较。我最后提到MSDN是因为,尽管有人说它不是一个“好理由”(但包作者提供的实现总是一个很好的指示您应该如何进行)。@KirkBroadhurst:在.NET标准库中,如果
    Close()
    方法甚至存在,它通常只是
    Dispose()的别名
    ,反之亦然。这也适用于导出WCF客户端的
    ClientBase
    ,文档甚至指出,处理客户端将关闭它。如果您想正确处理
    IDisposable
    对象,您可以始终使用
    Dispose
    方法,完全忘记
    Close
    ,因为这是多余的。
    var clt = new ChannelFactory<IOrderService>().CreateChannel();
    clt.PlaceOrder(foo);