利用lambda表达式正确关闭WCF连接
2013-06-11 21:28
387 查看
WCF是个好东西啊!用起来方便,功能强大,扩展性也比较大,但是WCF也有坑爹的地方,坑爹的地方就在于:
如何才能在客户端正确的关闭WCF连接!
如果你直接将客户端调用Close关闭,或者使用using语句,那你将是个悲剧,这点相信使用WCF的同志都知道的,因为ClientBase类的Close()方法被调用后,实际上是关闭了一个网络会话,并且会抛出异常!
这似乎违反常理,但确实发生了。因为一般来说Close函数都不会抛出异常。这个问题的解决办法是使用Try-Catch语句包含Close()方法,然后再异常处理中使用Abort函数释放资源!
同样,ClientBase类的IDisposable接口的实现函数Dispose方法中会调用Close函数,使用Reflector查看ClientBase<TChannel> 的代码便知
所以你使用using语句同样不能正确关闭WCF连接!而我们使用using语句就是为了不管发生什么情况,只要离开作用域之后,就会释放相关资源。而WCF的ClientBase类设计很明显违反了这一观念!简直是坑爹啊!
解决这一问题网上以后很多方案,首先说说微软的,也许是微软也意识到这一点,所以微软在提供的WCF示例程序中特意包含了一个叫做UsingUsing的示例,名字听起来有点怪
主要解决的方法是如下的代码
其实就是使用try-catch语句捕获关闭时的异常!试想要是每次都这样调用WCF服务将会是多么痛苦的一件事情!网上也有人使用Linq的Expression来解决这一问题
于是我借用函数式编程的思想,设计了一个使用lambda表达式来解决这一问题的方案!
关键的函数很简单,一看便知道是我是怎样设计的!
实际上这一设计的思想就是:将所有调用WCF服务的所有代码做为一个函数传入进来,然后我再内部使用try-catch语句包裹整个调用过程,这样就巧妙的将处理关闭连接异常的代码与实际调用过程分离开来!
函数的使用过程也比较方便
代码看起来比较简洁优美,个人比较满意,而且不用再担心调用结束后不能正确关闭WCF连接,资源不能正确释放的问题了!
如何才能在客户端正确的关闭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的示例,名字听起来有点怪
主要解决的方法是如下的代码
// This method shows the correct way to clean up a client, including catching the // approprate Exceptions. static void DemonstrateCleanupWithExceptions() { // Create a client CalculatorClient client = new CalculatorClient(); try { // Demonstrate a successful client call. Console.WriteLine("Calling client.Add(0.0, 0.0);"); double addValue = client.Add(0.0, 0.0); Console.WriteLine(" client.Add(0.0, 0.0); returned {0}", addValue); // Demonstrate a failed client call. Console.WriteLine("Calling client.Divide(0.0, 0.0);"); double divideValue = client.Divide(0.0, 0.0); Console.WriteLine(" client.Divide(0.0, 0.0); returned {0}", divideValue); // Do a clean shutdown if everything works. In this sample we do not end up // here, but correct code should Close the client if everything was successful. Console.WriteLine("Closing the client"); client.Close(); } catch (CommunicationException e) { // Because the server suffered an internal server error, it rudely terminated // our connection, so we get a CommunicationException. Console.WriteLine("Got {0} from Divide.", e.GetType()); client.Abort(); } catch (TimeoutException e) { // In this sample we do not end up here, but correct code should catch // TimeoutException when calling a client. Console.WriteLine("Got {0} from Divide.", e.GetType()); client.Abort(); } catch (Exception e) { // In this sample we do not end up here. It is best practice to clean up the // client if some unexpected Exception occurs. Console.WriteLine("Got unexpected {0} from Divide, rethrowing.", e.GetType()); client.Abort(); throw; } }
其实就是使用try-catch语句捕获关闭时的异常!试想要是每次都这样调用WCF服务将会是多么痛苦的一件事情!网上也有人使用Linq的Expression来解决这一问题
于是我借用函数式编程的思想,设计了一个使用lambda表达式来解决这一问题的方案!
关键的函数很简单,一看便知道是我是怎样设计的!
public static class SvcClient { public static void Invoke<TClient>(Action<TClient> act) where TClient : System.ServiceModel.ICommunicationObject, new() { TClient client = new TClient(); try { act(client); client.Close(); } catch (System.ServiceModel.CommunicationException) { client.Abort(); } catch (TimeoutException) { client.Abort(); } catch (Exception) { client.Abort(); throw; } } }
实际上这一设计的思想就是:将所有调用WCF服务的所有代码做为一个函数传入进来,然后我再内部使用try-catch语句包裹整个调用过程,这样就巧妙的将处理关闭连接异常的代码与实际调用过程分离开来!
函数的使用过程也比较方便
SvcClient.Invoke<Service1Client>(client => { //在此处添加调用WCF的代码 });
代码看起来比较简洁优美,个人比较满意,而且不用再担心调用结束后不能正确关闭WCF连接,资源不能正确释放的问题了!
相关文章推荐
- 利用lambda表达式正确关闭WCF连接
- (转)利用lambda表达式正确关闭WCF连接
- 在客户端正确的关闭WCF连接! zt
- C# lambda表达式参数的正确使用姿势
- WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭
- WCF连接被意外关闭
- ios利用正则表达式判断手机号码格式是否正确
- wcf 基础连接已经关闭,连接被意外关闭
- 正确关闭WCF代理对象
- 解决WCF传输大数据量时出错并提示:远程主机强迫关闭了一个现有的连接
- JDBC- 正确关闭数据库连接
- android studio 3.0版本下使用lambda表达式的正确配置姿势
- WCF-003:关于 WCF 基础连接已经关闭 连接被意外关闭-序列化问题
- iOS利用正则表达式验证邮箱格式是否正确
- 你正确关闭WCF链接了吗?
- ios利用正则表达式判断手机号码格式是否正确的实例
- 利用gcc对C语言的语句内嵌表达式扩展定义lambda宏
- 你正确关闭WCF链接了吗?
- ios利用正则表达式判断手机号码格式是否正确
- WCF 基础连接已经关闭: 连接被意外关闭。