博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在客户端正确的关闭WCF连接! zt
阅读量:7066 次
发布时间:2019-06-28

本文共 3983 字,大约阅读时间需要 13 分钟。

在客户端正确的关闭WCF连接!

如果你直接将客户端调用Close关闭,或者使用using语句,那你将是个悲剧,这点相信使用WCF的同志都知道的,因为ClientBase类的Close()方法被调用后,实际上是关闭了一个网络会话,并且会抛出异常!CommunicationException和TimeoutException!

这似乎违反常理,但确实发生了。因为一般来说Close函数都不会抛出异常。这个问题的解决办法是使用Try-Catch语句包含Close()方法,然后再异常处理中使用Abort函数释放资源!

同样,ClientBase类的IDisposable接口的实现函数Dispose方法中会调用Close函数,使用Reflector查看ClientBase<TChannel> 的代码便知

所以你使用using语句同样不能正确关闭WCF连接!而我们使用using语句就是为了不管发生什么情况,只要离开作用域之后,就会释放相关资源。而WCF的ClientBase类设计很明显违反了这一观念!简直是坑爹啊!

解决这一问题网上以后很多方案,首先说说微软的,也许是微软也意识到这一点,所以微软在提供的WCF示例程序中特意包含了一个叫做UsingUsing的示例,名字听起来有点怪

主要解决的方法是如下的代码

1 // This method shows the correct way to clean up a client, including catching the 2         // approprate Exceptions. 3         static void DemonstrateCleanupWithExceptions() 4         { 5             // Create a client 6             CalculatorClient client = new CalculatorClient(); 7             try 8             { 9                 // Demonstrate a successful client call.10                 Console.WriteLine("Calling client.Add(0.0, 0.0);");11                 double addValue = client.Add(0.0, 0.0);12                 Console.WriteLine("        client.Add(0.0, 0.0); returned {0}", addValue);13 14                 // Demonstrate a failed client call.15                 Console.WriteLine("Calling client.Divide(0.0, 0.0);");16                 double divideValue = client.Divide(0.0, 0.0);17                 Console.WriteLine("        client.Divide(0.0, 0.0); returned {0}", divideValue);18 19                 // Do a clean shutdown if everything works.  In this sample we do not end up20                 // here, but correct code should Close the client if everything was successful.21                 Console.WriteLine("Closing the client");22                 client.Close();23             }24             catch (CommunicationException e)25             {26                 // Because the server suffered an internal server error, it rudely terminated27                 // our connection, so we get a CommunicationException.28                 Console.WriteLine("Got {0} from Divide.", e.GetType());29                 client.Abort();30             }31             catch (TimeoutException e)32             {33                 // In this sample we do not end up here, but correct code should catch34                 // TimeoutException when calling a client.35                 Console.WriteLine("Got {0} from Divide.", e.GetType());36                 client.Abort();37             }38             catch (Exception e)39             {40                 // In this sample we do not end up here.  It is best practice to clean up the41                 // client if some unexpected Exception occurs.42                 Console.WriteLine("Got unexpected {0} from Divide, rethrowing.", e.GetType());43                 client.Abort();44                 throw;45             }46         }

其实就是使用try-catch语句捕获关闭时的异常!试想要是每次都这样调用WCF服务将会是多么痛苦的一件事情!网上也有人使用Linq的Expression来解决这一问题

于是我借用函数式编程的思想,设计了一个使用lambda表达式来解决这一问题的方案!

关键的函数很简单,一看便知道是我是怎样设计的!

1 public static class SvcClient 2     { 3         public static void Invoke
(Action
act) 4 where TClient : System.ServiceModel.ICommunicationObject, new() 5 { 6 TClient client = new TClient(); 7 try 8 { 9 act(client);10 client.Close();11 }12 catch (System.ServiceModel.CommunicationException)13 {14 client.Abort();15 }16 catch (TimeoutException)17 {18 client.Abort();19 }20 catch (Exception)21 {22 client.Abort();23 throw;24 }25 }26 }

实际上这一设计的思想就是:将所有调用WCF服务的所有代码做为一个函数传入进来,然后我再内部使用try-catch语句包裹整个调用过程,这样就巧妙的将处理关闭连接异常的代码与实际调用过程分离开来!

函数的使用过程也比较方便

1 SvcClient.Invoke
(client =>2 {3   //在此处添加调用WCF的代码4 });

代码看起来比较简洁优美,个人比较满意,而且不用再担心调用结束后不能正确关闭WCF连接,资源不能正确释放的问题了!

转载地址:http://xhtll.baihongyu.com/

你可能感兴趣的文章
查找组成一个偶数最接近的两个素数
查看>>
不怕狼一样的敌人,就怕狗一样的朋友
查看>>
bash基础特性
查看>>
【连载】物联网全栈教程-从云端到设备(十二)---最简单的单片机上云方法!...
查看>>
如何自学编程?学习方法在这里!
查看>>
springboot web应用 jar 启动 ant脚本
查看>>
SolrCould 集群搭建
查看>>
IDEA Git版本回滚提交方式
查看>>
tomcat中同时启动两个项目出现内存不足的错误提示解决办法
查看>>
ssm框架开发过程中遇到的一错误以及解决问题提示
查看>>
树的遍历
查看>>
Akka2使用探索6(Futures)——实现并发和异步
查看>>
【持续更新】jQuery 实用技巧
查看>>
大象也能起舞,Citrix X1计划让你对笔记本电脑say good bye
查看>>
Nginx 之常见报错问题解决
查看>>
linux 防爆破方法
查看>>
2、通过ipmitool工具修改IPMI的WEB密码
查看>>
云盘关闭,教你用蒲公英搭建私有云
查看>>
Spring Cloud 入门教程5、服务容错监控:Hystrix Dashboard
查看>>
很好的学习平台
查看>>