如果你调用WCF服务时,像下面的代码这样在using语句中进行调用,需要注意一个问题。

using (CnblogsWcfClient client = new CnblogsWcfClient())
{
client.Say("Hello, cnblogs.com!");
}

上面这段代码看上去没问题,CnblogsWcfClient是一个自动生成的WCF客户端代理,继承自System.ServiceModel.ClientBase。using语句结束时,会调用ClientBase实现的System.IDisposable.Dispose接口,实际就是调用ClientBase的Close()方法。用.NET Refector打开C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.ServiceModel.dll,可以看到这样的代码,见下图:

不仅看上去没问题,似乎就是没问题。但是...问题就出在ClientBase.Close()上,Close()要关闭的是一个网络连接,如果这时网络连接出现问题,不能正常关闭会引发异常(ClientBase的Close方法就是这样设计的,引发异常,而不是强制关闭),问题就来了。本来我们使用using的目的就是不管出现什么状况,即使天塌下来,也给我关闭掉;结果,关是关了,却没有闭,天还是塌下来了。

也许我们可以用“不可抗拒力”回避这个问题,但程序员的天性是解决问题。代码中任何一个小问题都不能忽视,因为我们很难预料这个小问题会不会带来大问题。

那如何解决这个问题呢?MSDN中有答案(去MSDN看看),代码如下:


CnblogsWcfClient client = new CnblogsWcfClient();
try
{
client.Say("Hello, cnblogs.com!");
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}

上面的代码显得有些哆嗦,如果你不关心是什么异常,只要出现异常就关闭的话,可以用下面的代码(代码来自TIP: Closing your WCF Connections properly):


CnblogsWcfClient client = new CnblogsWcfClient();
client.Say("Hello, cnblogs.com!");
try
{
if (client.State != System.ServiceModel.CommunicationState.Faulted)
{
client.Close();
}
}
catch (Exception ex)
{
client.Abort();
}

简化版代码:


CnblogsWcfClient client = new CnblogsWcfClient();
client.Say("Hello, cnblogs.com!");
try
{
client.Close();
}
catch
{
client.Abort();
}

好了,博客写好了,印象更深了,理解也更深了。在收获中分享,在分享中收获。

参考文章:

Avoiding Problems with the Using Statement

Closing your WCF Connections properly

相关链接:

WCF的问题和Using语句块

WCF中的Dispose

不要在using语句中调用WCF服务的更多相关文章

  1. iPhone中调用WCF服务

    本文介绍的是跨平台iPhone中调用WCF服务,WCF是由微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,由 .NET Framework 3.0+开始引入 iPhone中调用WC ...

  2. VS2010中使用Jquery调用Wcf服务读取数据库记录

    VS2010中使用Jquery调用Wcf服务读取数据库记录 开发环境:Window Servere 2008 +SQL SERVE 2008 R2+ IIS7 +VS2010+Jquery1.3.2 ...

  3. 完全使用接口方式调用WCF 服务

    客户端调用WCF服务可以通过添加服务引用的方式添加,这种方式使用起来比较简单,适合小项目使用.服务端与服务端的耦合较深,而且添加服务引用的方式生成一大堆臃肿的文件.本例探讨一种使用接口的方式使用WCF ...

  4. 实现在GET请求下调用WCF服务时传递对象(复合类型)参数

    WCF实现RESETFUL架构很容易,说白了,就是使WCF能够响应HTTP请求并返回所需的资源,如果有人不知道如何实现WCF支持HTTP请求的,可参见我之前的文章<实现jquery.ajax及原 ...

  5. 实现jquery.ajax及原生的XMLHttpRequest跨域调用WCF服务的方法

    关于ajax跨域调用WCF服务的方法很多,经过我反复的代码测试,认为如下方法是最为简便的,当然也不能说别人的方法是错误的,下面就来上代码,WCF服务定义还是延用上次的,如: namespace Wcf ...

  6. 实现jquery.ajax及原生的XMLHttpRequest调用WCF服务的方法

    废话不多说,直接讲解实现步骤 一.首先我们需定义支持WEB HTTP方法调用的WCF服务契约及实现服务契约类(重点关注各attribute),代码如下: //IAddService.cs namesp ...

  7. .NET Core 调用WCF 服务

    .NET Core 和ASP.NET Core 已经可以调用WCF 服务. 环境要求: VS2015 Update 2 +VS2015 Tooling + .NET Core SDK 下载地址: ht ...

  8. SharePoint 2013 调用WCF服务简单示例

    内容比较简单,主要记录自己使用SharePoint 2013WCF服务遇到的小问题和小经验,分享给大家,希望能够给需要的人有所帮助.好吧,进入正题! 第一部分 SharePoint 2013调用自带W ...

  9. [转]学习 WCF (6)--学习调用WCF服务的各种方法

    转自:http://www.cnblogs.com/gaoweipeng/archive/2009/07/26/1528263.html 作者这篇博文写得很全面. 根据不同的情况,我们可以用不同的方法 ...

随机推荐

  1. 【算法笔记】B1027 打印沙漏

    1027 打印沙漏 (20 分) 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇 ...

  2. P2056 [ZJOI2007]捉迷藏

    传送门 如果没有修改显然就直接点分治 有修改那就动态点分治 动态点分治就是在点分树上维护一些东西,查询时也在点分树上查 因为点分树深度是$log$的所以可以保证时间复杂度 此题我们需要在点分树上维护 ...

  3. poj1182 食物链 带权并查集

    题目传送门 题目大意:大家都懂. 思路: 今天给实验室的学弟学妹们讲的带权并查集,本来不想细讲的,但是被学弟学妹们的态度感动了,所以写了一下这个博客,思想在今天白天已经讲过了,所以直接上代码. 首先, ...

  4. [转] 使用Docker容器,这些错误千万别犯

    [From]http://www.maiziedu.com/article/23592/ 之前我写了一篇文章(作为ruby程序猿, 为什么非得用Docker?),里面详细讲了他的优点,相信大家都有所了 ...

  5. drf之序列化器的使用

    一.序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 完成数据校验功能 3. 反序列化,把客户端发送过来的数据,经 ...

  6. TCP/IP网络通信-数据传输

    1.通过网络IP实现数据的传输. 2.服务器端代码  [ 服务端主要通过Socket类来创建一个监听等待客户端连接,服务端发送用send方法,接收用Receive方法] using System.Ne ...

  7. java se系列(四) 函数、数组、排序算法、二分法、二维数组

    1 函数 1.1  数的概述 发现不断进行加法运算,为了提高代码的复用性,就把该功能独立封装成一段独立的小程序,当下次需要执行加法运算的时候,就可以直接调用这个段小程序即可,那么这种封装形形式的具体表 ...

  8. Kettle集群部署(1台Windows主机和2台Linux服务器)

    不多说,直接上干货! http://blog.csdn.net/jianglushou9763/article/details/70859616

  9. 【CAD】创建多行文本

    下面为OBJECT-ARX创建多行文本的代码,记录 McDbMText* Mx::AddMText(IN McDbBlockTableRecord* pBlkRec, IN LPCTSTR pszCo ...

  10. 【Java】使用Eclipse进行远程调试,Linux下开启远程调试

    原博地址:http://blog.csdn.net/dfdsggdgg/article/details/50730311 1.center下,在startup.sh文件首行中添加如下语句 declar ...