WCF技术剖析之九:服务代理不能得到及时关闭会有什么后果?

简介: 原文:WCF技术剖析之九:服务代理不能得到及时关闭会有什么后果?我们想对WCF具有一定了解的人都会知道:在客户端通过服务调用进行服务调用过程中,服务代理应该及时关闭。但是如果服务的代理不等得到及时的关闭,到底具有怎样的后果?什么要关闭服务代理?在任何时候都需要关闭服务代理吗?是否有一些例外呢?本篇文章将会围绕着这些问题展开。
原文: WCF技术剖析之九:服务代理不能得到及时关闭会有什么后果?

我们想对WCF具有一定了解的人都会知道:在客户端通过服务调用进行服务调用过程中,服务代理应该及时关闭。但是如果服务的代理不等得到及时的关闭,到底具有怎样的后果?什么要关闭服务代理?在任何时候都需要关闭服务代理吗?是否有一些例外呢?本篇文章将会围绕着这些问题展开。

一、会话信道(Sessionful Channel) V.S. 数据报信道(Datagram Channel)

WCF通过信道栈实现了消息的编码、传输及基于某些特殊功能对消息的特殊处理,而绑定对象是信道栈的缔造者,不同的绑定类型创建出来的信道栈具有不同的特性。就对会话的支持来讲,我们可以将信道分为以下两种:

  • 会话信道(Sessionful Channel):会话信道确保客户端和服务端之间传输的消息能够相互关联,但是信道的错误(Fault)会影响后续的消息交换;
  • 数据报信道(Datagram Channel):即使在同一个数据报信道中,每次消息的交换都是相互独立,信道的错误也不会影响后续的消息交换。

对于绝大部分绑定类型(BasicHttpBinding除外),在默认的情况下创建的都是会话信道。对于WCF客户端来说,如果进行基于会话信道的服务调用,有一些问题需要引起足够的重视,如果使用不当,不但影响客户端本身的服务调用,还会对服务处理请求的吞吐量造成很大的影响。

二、服务代理的关闭与并发会话(Concurrent Sessions)的限制

基于会话信道服务调用须要注意的第一个问题和WCF流量限制有关,为了使读者对这个问题先有一个直观认识,我们照例通过一个简单的实验来重现须要解决的问题。本例使用我们熟悉的计算服务例子,在服务寄宿的时候采用WsHttpBinding,下面是客户端程序。

   1: Binding binding = new WsHttpBinding(); EndpointAddress address = new EndpointAddress("http://127.0.0.1:9999/calculateservice"); ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(binding, address); for (int i = 1; i <= 20; i++)
   2: {
   3:     try
   4:     {
   5:         ICalculator calculator = channelFactory.CreateChannel();
   6:         Console.WriteLine("{3}: x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2), i);
   7:     }
   8:     catch (Exception ex) { Console.WriteLine("{0}t: {1}", i, ex.Message); }
   9: }

输出结果:

   1: 1 : x + y = 3 when x = 1 and y = 2
   2: 2 : x + y = 3 when x = 1 and y = 2
   3: ......
   4: 10: x + y = 3 when x = 1 and y = 2
   5: 11: x + y = 3 when x = 1 and y = 212:请求通道在等待 00:00:59.9840000以后答复超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能是更长超时的一部分

从输出的结果可以看出,虽然在代码中我们通过一个for循环进行了20次服务调用,但是真正成功执行的仅仅有11次,第12次进行服务调用的时候,抛出Timeout异常。这种情况的出现源于WCF对并发会话数量的控制。说得具体点,WCF对一个ServiceHost所能处理的并发会话作了限制,在默认的情况下,允许的最大并发会话数量为10。

那么细心的读者马上会问一个问题,既然默认的并发会话数量为10,为什么上面的例子中,会有11次成功的并发服务调用呢?这是因为,服务端的信道监听器允许一个额外的会话信道。在很多情况下,11个并发会话肯定是不能满足具体的需求的,那么是否可通过相应的配置根据具体的需求灵活指定一个合适的最大并发会话数量呢?答案是肯定的,服务允许的最大并发会话可以通过ServiceThrottlingBehavior服务行为的MaxConcurrentSessions属性进行配置。在下面的配置中,将该值设为了20。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:   <system.serviceModel>
   4:     <behaviors>
   5:       <serviceBehaviors>
   6:         <behavior name="highConcurrencyBehavior">
   7:           <serviceThrottling maxConcurrentSessions="20" />
   8:         </behavior>
   9:       </serviceBehaviors>
  10:     </behaviors>
  11:     ... ...
  12:   </system.serviceModel>
  13: </configuration>

WCF对服务的并发会话的限制给WCF客户端提出了一个要求,那就是在服务代理不再使用的情况下,应该及时将其关闭。基于服务代理对象的会话会随着服务代理的关闭而关闭。服务端在处理客户端请求的时候,如果当前并发的会话数量超过了所允许的范围,后续的请求将会被放入等待队列,以等待现有会话的结束。对于客户端来说,服务调用在允许的超时时限(默认1分钟)内还未接收到回复,则会抛出一个TimeoutException异常,如例子所表现的一样。如果能够及时地关闭服务代理对象,即使是2000次调用都没有问题,如下所示:

   1: Binding binding = new WSHttpBinding(); 
   2: EndpointAddress address = new EndpointAddress("http://127.0.0.1:9999/calculateservice"); 
   3: ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(binding, address); 
   4: for (int i = 1; i <= 2000; i++) 
   5: { 
   6:     ICalculator calculator = channelFactory.CreateChannel(); 
   7:     Console.WriteLine("{3}: x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2), i); 
   8:     (calculator as ICommunicationObject).Close(); 
   9: }

输出结果:

   1: 1 : x + y = 3 when x = 1 and y = 2
   2: 2 : x + y = 3 when x = 1 and y = 2
   3: ......
   4: 1999: x + y = 3 when x = 1 and y = 2
   5: 2000: x + y = 3 when x = 1 and y = 2

三、服务代理的关闭与否对数据报信道没有影响

上面讲的是对最大会话的限制,实际也可以说成是对最大会话信道的限制,那么对于非会话信道是否也有此限制呢?实践出真知,照例通过具体的例子来说明问题。我们知道绑定是信道的创建者,信道的特性通过组成绑定的元素(绑定元素)决定,所以信道对会话支持的特性也不例外。以上面例子使用的WsHttpBinding为例,只有WsHttpBinding的安全(Security)或可靠会话(Reliable Session)开启的情况下,创建的信道才具有会话的特性,否则创建出来的信道是不能支持信道的。在默认的情况下,WsHttpBinding的安全模式(SecurityMode)为基于消息的安全,所以创建出来的信道自动被赋予了会话的特性。

为了验证在非会话信道的情况下,WCF最大并发会话限制是否存在,我们对上面的代码稍加修改,在创建WsHttpBinding的时候,将安全模式设为SecurityMode.None(当然,在进行服务寄宿的时候,WsHttpBinding也须要进行相同的设置)。通过最终输出结果可以看出,MaxConcurrentSessions的限制不适合非会话邦定。

   1: Binding binding = new WSHttpBinding(SecurityMode.None); 
   2: EndpointAddress address = new EndpointAddress("http://127.0.0.1:9999/calculateservice"); 
   3: ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(binding, address); 
   4: for (int i = 1; i <= 2000; i++) 
   5: { 
   6:     ICalculator calculator = channelFactory.CreateChannel(); 
   7:     Console.WriteLine("{3}: x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2), i); 
   8: }

输出结果:

   1: 1 : x + y = 3 when x = 1 and y = 2
   2: 2 : x + y = 3 when x = 1 and y = 2
   3: ......
   4: 1999: x + y = 3 when x = 1 and y = 2
   5: 2000: x + y = 3 when x = 1 and y = 2


作者: Artech
出处: http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
目录
相关文章
|
9月前
|
前端开发
WCF更新服务引用报错的原因之一
WCF更新服务引用报错的原因之一
|
8月前
|
C# 数据安全/隐私保护
c#如何创建WCF服务到发布(SqlServer版已经验证)
c#如何创建WCF服务到发布(SqlServer版已经验证)
38 0
|
8月前
|
安全 数据库连接 数据库
WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构。该架构的项层为服务模型层。 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案。且能与已有系统兼容写作。 简单概括就是:一组数据通信的应用程序开发接口。
57 0
Visual Studio 2022 创建 WCF服务 找不到
Visual Studio 2022 创建 WCF服务 找不到
|
C++
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
102 0
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF使用纯代码的方式进行服务寄宿
服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用,除去上面的两种寄宿方式,还可以以纯代码的方式实现服务的寄宿工作。
850 0
|
Windows
WCF服务寄宿到IIS
一.WCF简介: Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台。整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTP和FTP的相关技术。
1046 0
WCF服务自我寄宿
WCF服务的寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有: IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。
994 0
|
安全 C#
WCF技术我们应该如何以正确的方式去学习掌握
一、WCF技术我该如何学习?       阿笨的回答是:作为初学者的我们,那么请跟着阿笨一起玩WCF吧,阿笨将带领大家如何以正确的姿势去掌握WCF技术。由于WCF技术知识点太多了,就纯基础概念性知识都可以单独出一本书来讲解,本次分享课程《C#面向服务编程技术WCF从入门到实战演练》开课之前,阿笨还是希望从没了解过WCF技术的童鞋们提前先了解一下WCF技术,至少要明白WCF技术的ABC三要素分别指的是什么。
1172 0
|
网络架构
(纯代码)快速创建wcf rest 服务
因为有一个小工具需要和其它的业务对接数据,所以就试一下看能不能弄一个无需配置快速对接的方法出来,百(以)度(讹)过(传)后(讹),最后还是对照wcf配置对象调试出来了: 1.创建WebHttpBinding 2.
979 0