实例上下文模式(IntanceContext Mode)表示服务端的服务实例与客户端的服务代理的绑定方式。

在WCF中有三种不同的实例上下文模式,单调(Per-Call)模式,会话(Per-Session),模式和单例(Single)模式.其中会话模式是默认的
 
单调模式:如果采用单调实例上下文模式,对于每一个服务调用,不论是来自相同的客户
端(服务代理)还是不同的客户端,WCF总是创建一个全新的服务实例和实例上下文
对象来处理服务调用请求。在服务操作执行完毕,实例上下文对象和被封装的服务实例
被回收掉.------------------------------------------------------------------------------只有这种模式资源可自动回收(要实现IDisposeable)
       
      

         对于实现了IDisposable接口的Dispose方法,有一点值得注意的是:该方法是以与操作
方法同步的形式执行的。也就是说,服务操作和Dispose方法在相同的线程中执行。
认识这一点很重要,因为无论采用怎样的实例模式,在支持会话的情况下如果服务请求
来自于同一个服务代理,服务操作都会在一个线程下执行。对于单调模式就会出现这样
的问题:由于Dispose方法同步执行的特性,如果该方法是一个比较耗时的操作,那么来
自于同一个服务代理的服务后续调用请求将不能得到及时执行。WCF只能在上一个服务
实例被成功释放之后,才能处理来自相同服务代理的下一个服务调用请求.
                                                                              单调模式最大的优势:能够最大限度的发挥资源的利用,避免了资源的闲置及相互争用
 
会话模式:会话的目的在于保持来自相同客户端(即同一个服务代理)多次服务调用
之间的状态。如果从消息交互的角度来讲,通过会话可以将来自相同客户端的多个
消息关联在一起。在会话实例上下文模式下,WCF为每一个服务代理对象分配一个单独
的服务实例上下文对象,对于来自相同服务代理的所有服务调用请求,都将分发给相同
的服务实例上下文处理。

             现在,先后100个客户端(或者服务代理)进行服务调用请求,毫无疑问,100个服务实例
会被创建并同时存在于服务端的内存之中,并且每一个服务实例引用一个开启状态的数据
库连接,那么当来自第101个客户端服务调用请求抵达时,将得不到处理,除非在它的超
时时限到达之前,有一个客户端自动将服务代理关闭.
 但是,对于相同的场景,如果采用单调的模式,就能应付自如,因为每次服务调用之后
,数据库的连接可以及时地得到关闭和释放.

                                                                                 较之会话模式,单调模式能够处理更多的并发客户端。
 
 
 

单例模式下,WCF通过创建一个唯一的服务实例来处理所有的客户端服务调用请求。
这是一个极端的服务实例激活方式,由于服务实例的唯一性,所有客户端每次调用的
状态能够被保存下来,但是当前的状态是所有客户端作用于服务实例的结果,它不能
反映出具体某个客户端多次调用后的状态。WCF是一个典型的多线程的通信框架,对并
发的服务调用请求是最基本的能力和要求,但是服务实例的单一性就意味着相同服务实例
需要在多个线程下并发地调用.
                                                                                 并发多时这种模式其实不是很好,它会受并发模式影响。但是我们可以设多线程并发模式。如下可以达到单调一样的效果。
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,ConcurrencyMode=ConcurrencyMode.Multiple)]
    public class Services:ICalculator
    {
        public double Add(double x, double y)
        {
            Thread.Sleep(5000);//单调不受它的影响,如是单例则要设多线程并发模式。如上
            return x + y;
        }
    }
   //在使用PerCall模式下,对于5个并发的服务调用均得到了及时的相应,这是我们希望看到
    //的结果.
   
    //在使用Single,情况就完全不一样了。从最终的结果可以看出,客户端得到执行
    //结果的间隔为5s.
    //WCF通过并发模式表示多线程访问单例服务对象的方式,而并发模式作为一种服务可以
    //通过ServiceBehaviorAttribute特性进行设定。WCF通过ConcurrencyMode枚举来表示
    //不同形式的并发模式,三个枚举值Single,Reentrant和Multiple分别表示单线程
    //重入,和多线程三种并发模式.

//ConcurrencyMode.Single是默认采用的并发模式,这正是上面的例子中服务操作同步执行
    //的根本原因。为了让服务操作异步的执行,以提供服务的响应能力,我们只需要通过
    //ServiceBehaviorAttribute将并发模式设为ConcurrencyMode.Multiple就可以了.

     对于单例上下文模式,如果采用传统的基于服务类型的寄宿方式,即通过服务类型而
非服务实例创建ServiceHost对象,服务实例是通过WCF内部的服务实例激活机制创建的
。不同于其他两种实例上下文模式采用请求式实例激活方式(单调实例上下文在处理每次
调用请求时创建,而会话实例上下文模式则在接收到某个客户端的第一次调用请求时创建
服务实例上下文),单例实例上下文模式在ServiceHost的初始化过程中被创建。我们把
这种模式称为隐式单例模式.
 
 

会话模式定义在服务契约中,通过ServiceContractAttribute特性的SessionMode属性定义.
定义在SessionMode的3个枚举值分别对应3种不同的会话模式:Allowed,Reqired和NotAllowed.
Allowed:允许会话,对会话的具体支持依赖于绑定对会话的支持.            默 认
Required:强制服务契约提供对会话的支持,如果绑定不支持会话,抛出异常。

NotAllowed:禁止会话.
默认使用的会话模式为SessionMode.Allowed,所以以下两种服务契约的定义方式是等效的.
[ServiceContract(Namespace=“http://***/”,SessionMode=SessionMode.Allowed)]
Public interface ICalculator
{
}
[ServiceContract(Namespace=“http://***/”)]
Public interface ICalculator
{
}
在进行基于会话服务调用中,会话开始于基于对应用服务代理的第一次服务调用,或者
通过Open方法人为开启服务代理.而当我们调用Close方法关闭服务代理的时候,也意味
着 会话结束.
 
会话模式的缺点:如果最大支持100个,但现在有101个进来,资源又没有被放(前台没有关)这时就会处于等待。
 

因此,会话实例上下文模式仅仅适合一些客户端数量很少的应用,并且在确定不使用服务
代理的时候,应该显示地将它们关闭
 
服务实例的释放。

可通过在服务的操作方法上应用OperationBehaviorAttribute特性设置相应的实例释放模式
,使实例在该操作方法执行之前或之后释放。实例释放模式通过System.ServiceMode.
ReleaseInstanceMode枚举表示.
ReleaseInstanceMode中的3个枚举值BeforeCall, AfterCall, BeforeAndAfterCall表示现有的服
务实例将在相应的操作执行之前,之后及前后被释放。默认值为
ReleaseInstanceMode.None,这 意味着不会执行基于该操作的实例释放操作在下面的
代码中,在Add方法中,通过OperationBehaviorAttribute特性将实例释放模式设置为
ReleaseInstanceMode.BeforeAndAfterCall,表明对于Add操作,WCF运行时每次都会为其
创建新的服务实例,并且该服务实例在完成该操作后会马上被释放.
 
 
 
 
小结:
 

1:尽可能使用PerCall服务.
2:对大规模的部署避免PerSession并发模式.
3:当需要PerSession服务时,尽量使用Single并发模式进行同步.
4:对于大规模服务器的部署,应避免Single并发模式.
5:总是检查代理状态,以确保服务器信道没有出现故障。
6:设置分流行为,使单一主机的进程每秒接受的请求约为300个,并确保调用者能得到新
的会话。
 
 
 
 

WCF实例上下文的更多相关文章

  1. WCF实例上下文模式与并发模式对性能的影响

    实例上下文模式 InstanceContextMode 控制在响应客户端调用时,如何分配服务实例.InstanceContextMode 可以设置为以下值: •Single – 为所有客户端调用分配一 ...

  2. [WCF编程]7.实例上下文模式

    一.实例上下文模式概述 实例上下文(IntanceContext Mode)表示服务端的服务实例与客户端的服务代理的绑定方式. 在实例化服务器对象时,WCF采用了3种不同的模式:单调(Per-Call ...

  3. WCF - 实例与会话

    实例上下文 实例上下文是对服务实例的封装 是WCF管理服务实例生命周期的依托  一个WCF服务通过ServiceHost进行寄宿 开启服务后当接收到请求 则会判断当前是否存在实例上下文 如果存在 则通 ...

  4. WCF实例管理的三种方式

    很多情况下,我们都需要控制wcf服务端对象的初始化方式,用来控制wcf实例在服务端的存活时间. Wcf框架提供了三种创建wcf实例的方式. WCF服务对象实例化基础 在普通的WCF请求和相应过程中,将 ...

  5. WCF入门(九)--WCF实例管理

    这组由Windows通讯基础(WCF)结合一组消息(客户端请求)服务实例所采用的技术被称为实例管理.一个完全由三种类型实例激活支持WCF,它们如下所述. 1.每个调用服务 每次调用服务是Windows ...

  6. wcf实例模型(随记)

    -----------------------------------------实例模型: 1.InstanceContentextMode: -------PerCall(单调):无状态,每次调用 ...

  7. JQuery Ajax调用WCF实例以及遇到的问题

    1.遇到的最多的问题就是跨域问题,这个时间需要我们添加如下代码解决跨域的问题 第一步:在服务类加Attribute [AspNetCompatibilityRequirements(Requireme ...

  8. 如何保证DBContext实例上下文唯一

    using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using S ...

  9. Android 调用WCF实例详解

    上篇文章已经对Web Service及其相关知识进行了介绍(Android开发之WebService介绍 ),相信有的朋友已经忍耐不住想试试在Android应用中调用Web Service.本文将通过 ...

随机推荐

  1. php cURL library is not loaded

    问题: php 在命令行里面可以找到 curl 模块,但是用apache 没有找到 curl 模块. 表现内容为: extension_loaded('curl')cURL library is no ...

  2. 【转】DataGridView绑定数据源的几种方式

    第一种:DataSet ds=new DataSet (); this.dataGridView1.DataSource=ds.Table[0]; 第二种:DataTable dt=new DataT ...

  3. IAR ERROR --- [Li006]

    今天移植代码时遇到一个比较奇葩的问题,记录如下: Error[Li006]: duplicate definitions for "Uart3"; in "E:\IAR_ ...

  4. CentOS 6,7最小化安装后再安装图形界面

    CentOS 6.2最小化安装后再安装图形界面 在安装CentOS 6.2时发现它没有提示我要怎么安装,而是“自作主张”地给我选择了最小化安装,结果装完之后只有终端界面,因为有时候不得不用图形界面,所 ...

  5. Jxl操作excel的demo

    网上很多例子,都是用Jxl读或者写excel,本文实现的功能就是将数据源in.xls的第几行第几列数据写入到out.xls的第几行第几列,不覆盖out.xls其他原有的数据. 需要导入的包:jxl.j ...

  6. PHP随机生成广告图片的实例 代码

    PHP随机生成广告图片: <?php /*  +------------------------------------------------------------------+  | Mi ...

  7. WPF处理Windows消息

    WPF中处理消息首先要获取窗口句柄,创建HwndSource对象 通过HwndSource对象添加消息处理回调函数. HwndSource类: 实现其自己的窗口过程. 创建窗口之后使用 AddHook ...

  8. 【转】perl中尖括号运算符(<>)使用说明

    perl中尖括号运算符的用途分享,这里简单介绍下,方便需要的朋友 perl中<>运算符可以有如下的用途: 1)如果尖括号中间是文件句柄,尖括号运算符允许你读取文件句柄,比如<STDI ...

  9. Oracle外部表的使用

    外部表可以像其它表一样,用select语句作查询.但不能做DML操作,不能建index,不接受约束.这是因为它不是以段的形式存于数据库中,只是以数据字典构造存在,指向一个或多个操作系统文件. 外部表的 ...

  10. WPF常用数据绑定控件集合

    1.怎么用ListView控件把XML中的数据在界面上显示出来? <?xml version="1.0" encoding="utf-8" ?> & ...