如果你调用WCF服务时像下面的代码这样在using语句中进行调用需要注意一个问题 using(CnblogsWcfClientclient=newCnblogsWcfClient()) { clientSay(Hello!); }
上面这段代码看上去没问题CnblogsWcfClient是一个自动生成的WCF客户端代理继承自SystemServiceModelClientBaseusing语句结束时会调用ClientBase实现的SystemIDisposableDispose接口实际就是调用ClientBase的Close()方法用NET Refector打开C:\Windows\MicrosoftNET\Framework\v\SystemServiceModeldll可以看到这样的代码见下图 )thiswidth=; height=> 不仅看上去没问题似乎就是没问题但是问题就出在ClientBaseClose()上Close()要关闭的是一个网络连接如果这时网络连接出现问题不能正常关闭会引发异常(ClientBase的Close方法就是这样设计的引发异常而不是强制关闭)问题就来了本来我们使用using的目的就是不管出现什么状况即使天塌下来也给我关闭掉;结果关是关了却没有闭天还是塌下来了 也许我们可以用不可抗拒力回避这个问题但程序员的天性是解决问题代码中任何一个小问题都不能忽视因为我们很难预料这个小问题会不会带来大问题 那如何解决这个问题呢?MSDN中有答案(去MSDN看看)代码如下 CnblogsWcfClientclient=newCnblogsWcfClient(); try{ clientSay(Hello!); clientClose(); } catch(CommunicationExceptione) { clientAbort();}catch(TimeoutExceptione) { clientAbort();}catch(Exceptione) { clientAbort(); throw; }
上面的代码显得有些哆嗦如果你不关心是什么异常只要出现异常就关闭的话可以用下面的代码(代码来自TIP: Closing your WCF Connections properly) CnblogsWcfClientclient=newCnblogsWcfClient(); clientSay(Hello!); try{ if (clientState!=SystemServiceModelCommunicationStateFaulted) { clientClose(); } } catch (Exceptionex) { clientAbort(); }
简化版代码 CnblogsWcfClientclient=newCnblogsWcfClient(); clientSay(Hello!); try{ clientClose(); } catch{ clientAbort(); } |