WCF系列教程之WCF实例化

本文参考自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(1, 2),client.GetInstanceCount(),client.GetInstanceId(),client.GetOperationCount());
            Console.WriteLine("3+3={0},这是第{1}个实例上下文对象,实例ID是:{2},方法的操作数:{3}", client.AddMethod1(3, 3), 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会为每一个会话创建一个上下文实例
    )]

重新部署工程

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

时间: 2024-10-25 14:59:13

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

WCF系列教程之WCF服务宿主

本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆. 一.简介 任何一个程序的运行都需要依赖一个确定的进程中,WCF也不例外.如果我们需要使用WCF服务,那么我们就必须将服务寄宿与创建它并控制它的上下文和生存期的运行时环境当中,承载服务的环境,称之为宿主.WCF服务可以在支持托管代码的任意Windows进程中运行.WCF提供了统一编程模型,用于生成面向服务的应用程序.此编程模型保持一致且独立于部署服务的运行时环境

WCF系列教程之WCF服务配置

简介:WCF作为分布式开发的基础框架,在定义服务以及消费服务的客户端时可以通过配置文件的方式,来进行设置,这充分的体现了WCF的伸缩性和自定义性.当然WCF也提供硬编程的方式,通过在代码中直接设置相关对象的属性来完成服务端与客户端的配置,然而这种方式并不利于后期程序的更改和扩展. 1.WCF配置文件结构如下图所示,包含三个部分,services(服务).bindings()

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

本文参考自:http://www.cnblogs.com/wangweimutou/p/4414393.html,纯属读书笔记,加深记忆 一.简介 当我们打开WCF基础客户通道,无论是显示打开还是通过调用操作自动打开.使用客户端或者通过对象调用操作,或者关闭基础客户端通道,都会在客户端应用程序中出现异常,WCF是基于网络的通讯服务,错误异常也是要基于消息传递的,在WCF中提供了一个错误消息处理的类FaultException,WCF客户端可以通过它,来接收服务端传递回来的异常信息. 二.WCF异

WCF系列教程之WCF服务协定

本文参考自:http://www.cnblogs.com/wangweimutou/p/4422883.html,纯属读书笔记,加深记忆 一.服务协定简介: 1.WCF所有的服务协定层里面的服务接口,都有一个ServiceContract的特性修饰,服务接口里面的操作方法都有OperationContract特性修饰,why? (1).服务契约的实现要靠ServiceContractAttribute 属性定义 (2).服务契约方法的实现要靠 OperationContractAttribute

kali linux 系列教程之metasploit 连接postgresql可能遇见的问题

kali linux 系列教程之metasploit 连接postgresql可能遇见的问题 文/玄魂   目录 kali linux 下metasploit 连接postgresql可能遇见的问题................................ 1 前言............................................................................................................... 1

集群系列教程之:keepalived+lvs 部署

集群系列教程之:keepalived+lvs 前言:最近看群里很多人在问keepalived+lvs的架构怎么弄,出了各种各样的问题,为此特别放下了别的文档,先写一篇keepalived+lvs架构的文档,使那些有需求的人能够得以满足.但是此篇文档是架构文档,不是基础理论,但我想你能做这个架构,势必也了解了基础理论知识,更多的理论知识体系,请看下回分解.... 测试拓扑: 环境说明: 从上面的拓扑图,就可以看出本实验的环境信息,其中实线代表的是真实的物理连接,而虚线表示的是逻辑关系.hostna

Android系列教程之Activity的生命周期

通过上一节"Android系列教程之Android项目的目录结构"我们已经知道了什么是Activity,那么为什么我们创建一个Activity的导出类的时候为什么都要覆盖Activity的onCreate方法呢,为什么会在onPause()方法中保存一些当前Activity中的变化,要弄明白这些就要先了解Activity的生命周期,也就是一个Activity才开始到结束都要经过那些状态,下面通过一个例子了解Activity的声明周期. 一:Activity的生命周期方法 Android

iOS系列教程之TextKit实现图文混排读后记

iOS系列教程之TextKit实现图文混排读后记 前两天看搜狐家明哥写的<TextKit实现图文混排> 今晚回家看了下API发现了一个更加取巧的实现方式.可以直接将后台返回的html富文本用textView显示出来. 记得两年前当时做这个的时候还是借助了笨重的webview. > Textkit是iOS7新推出的类库,其实是在之前推出的CoreText上的封装,有了这个TextKit,以后不用再拿着CoreText来做累活了, 下面是我分别用UITextView 和UIWebView 显

kali Linux系列教程之BeFF安装与集成Metasploit

kali Linux系列教程之BeFF安装与集成Metasploit 文/玄魂 1.1 apt-get安装方式 1.2 启动 1.3 基本测试 1.4 异常信息 1.5 从源码安装BeEF 1.5.1 安装curl git 1.5.2 安装rvm 1.5.3 安装依赖项 1.5.4 安装ruby 1.5.5 安装bundler 1.5.6下载beef 1.5.7 安装和启动 1.6 集成metasploit 1.1 apt-get安装方式 打开终端,输入如下命令: apt-get install