本文参考自http://www.cnblogs.com/wangweimutou/p/4517951.html,纯属读书笔记,加深记忆

一、理解WCF实例化机制

1、WCF实例化,是指对用户定义的服务对象以及与其相关的实例上下文对象的生存期的控制,也就是说每一个服务类其实就是一个服务实例,客户端在调用服务端中的服务方法时,需要实例化一个服务端代理类对象,实例化就是对这个对象的生命周期的管理。

2、实例化行为(使用 System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode 属性进行设置),InstanceContextMode属性有两个作用:

(1)、控制如何创建 InstanceContext 以响应传入的消息

(2)、每个 InstanceContext 都与一个用户定义服务对象相关联,因此设置 InstanceContextMode 属性也可以控制用户定义服务对象的实例化

默认情况下,InstanceContextMode 枚举定义了实例化模式。可以使用下列实例化模式:

(1)、PerCall:单调模式,为每个客户端请求创建一个新的 InstanceContext(以及相应的服务对象)。

(2)、PerSession:会话模式,这是InstanceContextMode的默认值,为每个新的客户端会话创建一个新的 InstanceContext(以及相应的服务对象),并在该会话的生存期内对其进行维护(这需要使用支持会话的绑定).

(3)、Single:单例模式,单个 InstanceContext(以及相应的服务对象)处理应用程序生存期内的所有客户端请求。

二、实例化模式PerCall、PerSession、Single详解

1、单调模式

单调模式中,WCF总是创建一个新的服务实例上下文来处理请求对象,即客户端每调用一次方法就会创建一个实例上下文对象,调用完成靠GC完成释放对象(但是GC的回收具有不确定性,所以会有延迟),在调用下一个方法会创建下一个实例上下文,因此,一个会话通道可能会出现多个实例上下文对象。

代码实例:

1、WCF服务层搭建:新建契约层、服务层、和WCF宿主,添加必须的引用(这里不会的参考本人前面的随笔),配置宿主,生成解决方案,打开Host.exe,开启服务。具体的代码如下:

IPerCall.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks; namespace IService
{
[ServiceContract
(
SessionMode=SessionMode.Required
)
]
public interface IPerCall
{
[OperationContract]
int AddMethod(int a, int b);
[OperationContract]
int AddMethod1(int a, int b);
[OperationContract]
string GetInstanceId();//获取实例Id
[OperationContract]
int GetInstanceCount(); //获取实例数
[OperationContract]
int GetOperationCount(); //获取调用操作方法的计数器 }
}

PerCall.cs

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks; namespace Service
{
[ServiceBehavior
(
InstanceContextMode=InstanceContextMode.PerCall//设置当前服务类的实例化模式为单调模式,每调用一次方法,生成一个上下文实例
)]
public class PerCall:IPerCall
{
int operationCount;
static int instanceCount;
string instanceId;
public PerCall() {
instanceCount++;
instanceId = Guid.NewGuid().ToString();
}
public string GetInstanceId()
{
return instanceId;
} public int GetOperationCount()
{
return operationCount;
} public int AddMethod(int a, int b)
{
operationCount++;
return a + b;
} public int AddMethod1(int a, int b)
{
operationCount++;;
return a + b;
} public int GetInstanceCount()
{
return instanceCount;
}
}
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks; namespace Host
{ class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Service.PerCall)))
{
host.Open();
Console.WriteLine("服务已启动,按任意键中止...");
Console.ReadKey(true);
host.Close();
}
}
}
}

App.Config

<?xml version="1.0"?>
<configuration>
<system.serviceModel> <services>
<service name="Service.PerCall" behaviorConfiguration="mexBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/PerCall/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="IService.IPerCall" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

ok,打开Host.exe

服务开启成功!

2、新建一个名为Client的客户端控制台应用程序,添加对http://localhost:1234/PerCall/的引用

(1)、单调模式

program.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Client
{
class Program
{
static void Main(string[] args)
{
Client.PerCallClientNS.PerCallClient client = new PerCallClientNS.PerCallClient();
Console.WriteLine("1+2={0},这是第{1}个实例上下文对象,实例ID是:{2},方法的操作数:{3}", client.AddMethod(, ),client.GetInstanceCount(),client.GetInstanceId(),client.GetOperationCount());
Console.WriteLine("3+3={0},这是第{1}个实例上下文对象,实例ID是:{2},方法的操作数:{3}", client.AddMethod1(, ), client.GetInstanceCount(), client.GetInstanceId(), client.GetOperationCount());
Console.ReadKey();
}
}
}

通过结果分析,客户端通过会话通过每调用一次服务端的方法,就会创建一个服务端上下文实例,通过这个变量就可以看出

所以除非当前通道关闭,要不然只要调用一次当前服务端的方法,那么实例树还会继续上升。

(2)、单例模式(Single)

在单例模式中,WCF只会创建一个实例上下文来处理服务的所有的请求调用对象,即PerCall只会被实例化一次,不管调用的请求对象是在同一个客户端还是在不同的客户端.

代码实例,在上面代码的基础上将PerCall类的ServiceBehavior属性

 [ServiceBehavior
(
InstanceContextMode=InstanceContextMode.PerCall//设置当前服务类的实例化模式为单调模式,每调用一次方法,生成一个上下文实例
)]

修改成

[ServiceBehavior
(
InstanceContextMode=InstanceContextMode.Single//设置当前服务类的实例化模式为单例模式,只生成一个上下文实例,所以客户端共享这一个实例
)]

重新部署工程

不管执行多少次,当前总是第一个实例,说明当前上下文只生成了一个,应为没有执行构造函数,所以只能是1,但是操作数的增加,说明了,客户端共享了这一个实例,只要当前通道不关闭,那么操作数会一直增加。

(3)、会话模式(PerSession)

在会话模式(PerSession)中,WCF会对客户端与服务端的每一个会话通道创建一个实例上下文。即不同的客户端在各自的会话通道的实例上下文中处理请求对象。

在上面代码的基础上将PerCall类的ServiceBehavior属性的InstanceContextMode,修改成

[ServiceBehavior
(
InstanceContextMode=InstanceContextMode.PerSession//设置当前服务类的实例化模式为会话模式,WCF会为每一个会话创建一个上下文实例
)]

重新部署工程

每调用一次客户端,生成一个上下文实例,每次都是新的实例

WCF系列教程之WCF实例化的更多相关文章

  1. WCF系列教程之WCF服务协定

    本文参考自:http://www.cnblogs.com/wangweimutou/p/4422883.html,纯属读书笔记,加深记忆 一.服务协定简介: 1.WCF所有的服务协定层里面的服务接口, ...

  2. WCF系列教程之WCF服务宿主与WCF服务部署

    本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆. 一.简介 任何一个程序的运行都需要依赖一个确定的进程中,WCF ...

  3. WCF系列教程之WCF服务配置工具

    本文参考自http://www.cnblogs.com/wangweimutou/p/4367905.html Visual studio 针对服务配置提供了一个可视化的配置界面(Microsoft ...

  4. WCF系列教程之WCF服务配置

    文本参考自:http://www.cnblogs.com/wangweimutou/p/4365260.html 简介:WCF作为分布式开发的基础框架,在定义服务以及消费服务的客户端时可以通过配置文件 ...

  5. WCF系列教程之WCF消息交换模式之单项模式

    1.使用WCF单项模式须知 (1).WCF服务端接受客户端的请求,但是不会对客户端进行回复 (2).使用单项模式的服务端接口,不能包含ref或者out类型的参数,至于为什么,请参考C# ref与out ...

  6. WCF系列教程之WCF中的会话

    本文参考自http://www.cnblogs.com/wangweimutou/p/4516224.html,纯属读书笔记,加深记忆 一.WCF会话简介 1.在WCF应用程序中,回话将一组消息相互关 ...

  7. WCF系列教程之WCF客户端异常处理

    本文参考自:http://www.cnblogs.com/wangweimutou/p/4414393.html,纯属读书笔记,加深记忆 一.简介 当我们打开WCF基础客户通道,无论是显示打开还是通过 ...

  8. WCF系列教程之WCF客户端调用服务

    1.创建WCF客户端应用程序需要执行下列步骤 (1).获取服务终结点的服务协定.绑定以及地址信息 (2).使用该信息创建WCF客户端 (3).调用操作 (4).关闭WCF客户端对象 二.操作实例 1. ...

  9. WCF系列教程之WCF操作协定

    一.简介 1.在定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationContract ...

随机推荐

  1. UVa 11925 Generating Permutations (构造法)

    题意:给定一个序列,让你从一个升序列变成该序列,并且只有两种操作,操作1:交换前两个元素,操作2:把第一个元素移动到最后. 析:一开始的时候吧,不会,还是看的题解,首先是要逆序来做,这样可能好做一点, ...

  2. Python之模块和包学习

    模块简介 python是由一系列的模块组成的,每个模块就是一个py为后缀的文件,同时模块也是一个命名空间,从而避免了变量名称冲突的问题.模块我们就可以理解为lib库,如果需要使用某个模块中的函数或对象 ...

  3. 无线破解那点事(PJ)

    有一段时间没有写博客了.只能说苦逼学生党伤不起啊,还好没挂-废话不说了,近期将会讲讲无线PJ那点事,也不是啥干货,就一些先前的笔记分享把. 0.无线网卡 想要提高破解效率,一块猛一点的USB无线网卡是 ...

  4. BOM Open Interface. Import Bills and Routings 无法打开

    问题: 最近要做一些关于BOM的接口问题,用自己装好的 VM Linux Oracle EBS R12 Vision详细研究下关于BOM的 Open Interface: BOM.Substitute ...

  5. Unity3d中使用Lua

    对于手机游戏,如果可以在线更新以实现bug修复.新功能添加等等,其好处自不必多说. 通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考 http://docs.unity3d.com/ ...

  6. Centos7 创建Eclipse启动

    Eclipse是一个集成开发环境(IDE),包含一个基工作区和定制环境的可扩展插件系统.大部分使用 Java 编写,Eclipse 可以用来开发应用程序.通过各种插件,Eclipse 也可以用于其他编 ...

  7. 其他信息: 实体类型 xxxxx 不是当前上下文的模型的一部分。

    我是手动添加的EF类的,   解决方法: 没有在DbContext 添加  public virtual DbSet<xxx> xxxx{ get; set; } 导致不在上下文中

  8. django drf 自定义jwt用户验证逻辑

    新建Backend类 from django.contrib.auth.backends import ModelBackend from django.shortcuts import render ...

  9. cesium编程入门(四)界面介绍及小控件隐藏

    感性认识 界面介绍,viewer Geocoder : 查找位置工具,查找到之后会将镜头对准找到的地址,默认使用bing地图 Home Button :视角返回初始位置. Scene Mode Pic ...

  10. JS获取节点属性个数及值得方法

    var ex = node; ; for (var j in ex) { alert("" + myIndex + ".(<font color='blue'> ...