`

不要在using语句中调用WCF服务

阅读更多

如果你调用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();
}

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

原文地址:http://www.cnblogs.com/dudu/archive/2011/01/18/1938144.html

分享到:
评论

相关推荐

    silverlight学习之路(2)异步编程趋于同步 利用async和await调用wcf服务

    而本文将探讨的是如何在Silverlight应用中利用异步编程模型,特别是`async`和`await`关键字,来调用WCF(Windows Communication Foundation)服务,从而实现更高效的程序执行。 首先,让我们理解异步编程的重要性。...

    winform里直接使用WCF例子

    然后,在Winform项目中,我们可以通过服务引用来调用WCF服务。例如,在按钮点击事件处理程序中: ```csharp private void button1_Click(object sender, EventArgs e) { ServiceReference1.Service1Client client ...

    WCF写的小例子涉及到WCF中的事务

    4. **事务处理**:在代理类的`Transfer()`方法中,使用`using (new TransactionScope())`语句创建事务上下文,然后调用服务的`Transfer()`方法。如果所有操作成功,`TransactionScope.Complete()`将提交事务;如果...

    spring.net+Nhiberate实现WCF服务层

    在服务实现中,注入Spring.NET容器提供的SessionFactory,利用NHibernate来处理数据操作。例如: ```csharp [ServiceContract] public interface IWcfService { [OperationContract] List<User> GetAllUsers(); }...

    《WCF按部就班学习系列7_WCF事务概述》

    通过这些代码,你可以看到如何在服务和客户端中配置和使用事务,以及如何处理事务异常。 通过这个学习系列,你可以了解WCF服务中事务的完整概念,从基础到实践,从而能够设计和实现可靠的分布式系统。实际应用中,...

    WebForm引入WCF服務的四步驟.docx

    完成以上四个步骤后,你的WebForm应用就可以成功地调用WCF服务了。需要注意的是,虽然在开发和测试环境中禁用安全模式简化了配置,但在生产环境中,应根据具体的安全需求启用适当的安全模式,确保数据传输的安全性。

    如何同步和异步调用WCF服务

    通过阅读"如何同步和异步调用WCF服务"的文档,以及查看WCFCallExample.zip中的示例代码,开发者可以学习到如何在C#环境中有效地利用WCF服务。掌握同步和异步调用不仅能够提高程序效率,还能优化用户体验,特别是在UI...

    WCF客户端代码例子

    通过以上步骤,我们可以创建一个基本的WCF客户端并在asp.net c#环境中与服务进行通信。在实际项目中,可能还需要考虑性能优化、服务发现、负载均衡等高级特性。记住,始终确保服务和客户端的配置匹配,以便成功通信...

    WCF编码规范_中文版.pdf

    关于WCF服务的代码编写,文件提到了一些应该避免的做法,比如在服务类中直接使用[ServiceContract]和[OperationContract]属性,以及应当在接口上定义契约,然后在类中实现该接口。此外,还应当注意方法的实现应当...

    c# dll封装以及调用

    2. **导入命名空间**:在需要使用DLL的类或文件中,使用`using`语句导入DLL的命名空间。 3. **实例化对象**:根据DLL中的类定义创建对象,可以使用`new`关键字,或者如果类是静态的,可以直接调用静态方法。 4. **...

    rabbitmq-dotnet-client-3.6.4-dotnet-4.6.1.rar

    7. **WCF服务集成**:将RabbitMQ客户端库的调用封装到WCF服务操作中,作为服务接口的一部分,以便其他客户端可以通过服务调用来发送或接收消息。 8. **异常处理和资源管理**:确保在完成操作后关闭通道和连接,防止...

    Windows phone实现对SQL 2008数据库的插入操作

    本教程主要探讨如何在Windows Phone(WP)应用中通过Windows Communication Foundation (WCF)服务与SQL Server 2008数据库进行通信,特别是进行数据插入操作。其他的基本数据操作,如更新、删除和查询,可以通过类似...

    SilverLight与数据库的操作.pdf

    在这个示例中,我们将利用Silverlight 3与WCF(Windows Communication Foundation)服务通信,通过MSSQL数据库验证用户登录信息。 首先,确保您已经安装了必要的开发环境:Visual Studio 2008 SP1,Silverlight 3 ...

    Beginning ASP.NET Databases using C#

    同时,Web Services(如WCF)可以使得数据库服务化,让不同客户端都能远程调用数据库操作。 7. **安全性**:在处理数据库时,安全性是至关重要的。ASP.NET提供了各种机制来防止SQL注入、跨站脚本攻击等安全问题。...

    C#入门经典第四版的例题源代码D28-36

    - using语句:学习如何使用using语句管理资源,确保资源在使用后正确释放。 3. **Chapter 29:集合与泛型** - 集合:介绍ArrayList、LinkedList、HashTable等基本集合类型,以及它们之间的区别。 - 泛型:讲解...

    提高ASP.Net应用程序性能的十大方法

    在使用Web服务(如WCF)或远程过程调用(如Remoting)时,应注意避免不必要的数据传输。对于频繁调用的服务端点,应考虑采用异步调用方式以降低延迟。 #### 6. 图片和其他静态资源的优化 对图片等静态资源进行压缩...

Global site tag (gtag.js) - Google Analytics