实例上下文模式:单调模式

在创建一个服务端的时候都会依托于ServiceHost对象,里面存在一个SingletonInstance指向一个服务实例。而ServiceHost最终都是寄在InstanceContext中。对于单调模式,客户端的每次调用服务端都会创建一个全新的上下文和服务实例。

为了验证上述流程,写了下面这个例子。ServiceBehavior中的InstanceContextMode可以设置服务类型的上下文模式,公三种PerCall、PerSession、Single分别对应单调、回话、单例。这里设置为PerCall。

服务端用了一个Timer定时器,每隔100ms调用GC回收一次垃圾数据。Calculator中定义了构造函数和析构函数,方便看清服务端服务实例的声明周期。

using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Timer T = new Timer(s => GC.Collect(), null, 0, 100);
            ServiceHost host = new ServiceHost(typeof(Calculator));
            host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://localhost:4216");
            host.Opened += delegate { Console.WriteLine("Service Start!"); };
            host.Open();
            Console.Read();
        }
    }    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        int Add(int x, int y);
    }
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
    public class Calculator : ICalculator,IDisposable
    {
        public Calcilator()
        {
            Console.WriteLine("构造函数Calculator");
        }
        public int Add(int x, int y)
        {
            return x + y;
        }
     ~Calcilator()
        {
            Console.WriteLine("析构函数Calculator");
        }
        public void Dispose()
        {
            Console.WriteLine("Dispose方法");
        }
    }
}

客户端调用:

 static void Main(string[] args)
        {
          ICalculator channel =  ChannelFactory<ICalculator>.CreateChannel(new WSHttpBinding(), new EndpointAddress("http://localhost:4216"));
          channel.Add(1, 2);
          channel.Add(3, 4);
        }

输出:

可以看到,对于客户端的每次调用,都是新建了服务实例。

也可以自定义Attribute实现。IInstanceContextProvider是上下文提供者,GetExistingInstanceContext方法获取当前上下文实例,如果当前没有实例则会创建一个新的上下文。这里返回null,让它创建新的上下文。IsIdle方法返回true,意味着这个上下文实例是空闲的,GC可以回收。InitializeInstanceContext和NotifyIdle不实现。

 public class PerCallServiceProvider : IInstanceContextProvider
    {
        public InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel)
        {
            return null;
        }

        public void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)
        {}

        public bool IsIdle(InstanceContext instanceContext)
        {
            return true;
        }
        public void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)
        {
        }
    }

接下来将对每个终结点分发器都创建一个新的InstanceContextProvider。

public class PerCallAttribute : Attribute, IServiceBehavior
    {
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {}
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher channel in serviceHostBase.ChannelDispatchers)
            {
                foreach (EndpointDispatcher endpoint in channel.Endpoints)
                {
                    endpoint.DispatchRuntime.InstanceContextProvider = new PerCallServiceProvider();
                }
            }
        }
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {}
    }

服务端使用如下,也能实现单调的效果。

    [PerCall]
    public class Calcilator : ICalculator,IDisposable
    {.....}
时间: 2024-10-15 14:11:49

实例上下文模式:单调模式的相关文章

实例上下文模式:会话模式

一.会话模式简介与示例代码   会话模式下,客户端和服务实例上下文.服务实例是一一对应关系,每一个客户端都在服务端都有自己对应的服务实例上下文.如下图所示                  服务端使用会话模式的条件: 1.使用支持会话模式的绑定,如WSHttpBinding.WS2007HttpBinding.NetTcpBinding.NetNamedPipeBinding. 不支持会话的绑定有 BasicHttpBinding.NetMsmqBinding.Msmq属于离线状态的绑定,交互使

实例上下文模式:单例模式

单例模式效果可以用下面这张图表示,服务端的服务实例只有一个,任何一个客户端访问的服务端都是相同的服务实例.意味着服务端可以留下不同客户端的脚印. 使用也很简单,只需要将ServiceBehavior的上下文模式InstanceContextMode设置为Single即可.可以参照上一篇介绍实例上下文模式:单调模式 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class Calculator :

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

实例上下文模式 InstanceContextMode 控制在响应客户端调用时,如何分配服务实例.InstanceContextMode 可以设置为以下值: •Single – 为所有客户端调用分配一个服务实例. •PerCall – 为每个客户端调用分配一个服务实例. •PerSession – 为每个客户端会话分配一个服务实例. InstanceContextMode 的默认设置为 PerSession 并发模式ConcurrencyMode 控制一次允许多少个线程进入服务.Concurre

学习ASP.NET MVC框架揭秘笔记-实例演示:SC模式的应用

实例演示:SC模式的应用 为了对SC模式下的MVP,尤其是该模式下的View和Presenter之间的交互方式有一个深刻的认识,我们现在来做一个实例演示.我们采用员工查询的场景,用ASP.NET Web Forms来建立这个简单的应用. 我们先来定义员工的数据类型,Employee来表示一个员工,有5个属性:ID.姓名.性别.出生日期和部门. public class Employee { public string Id { get; private set; } public string

java中多线程通信实例:生产者消费者模式

线程间的通信: 其实就是多个线程再操作同一个资源,但是操作的动作不同   当某个线程进入synchronized块后,共享数据的状态不一定满足该线程的需要,需要其他线程改变共享数据的状态后才能运行,而由于当时线程对共享资源时独占的,它必须解除对共享资源的锁定的状态,通知其他线程可以使用该共享资源. Java中的 wait(),notify(),notifyAll()可以实现线程间的通信. 生产者--消费者问题是典型的线程同步和通信问题 /** * 生产者和消费者问题,生产者生成出产品,消费者去购

.Net简单工厂模式,工厂模式,抽象工厂模式实例

1.定义   简单工厂模式:是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类. 抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.实例 用工人种蔬菜的例子来说明,蔬菜植物的产品器官有根.茎.叶.花.果等5类,因此按产品器官分类也分成5种,分别是根菜类,茎菜类,叶莱类,花菜类以及果菜类.我们以根菜类,茎菜类为例,

WCF实例上下文与并发

一.实例上下文模式(InstanceContextMode)可以简单地理解为服务端的服务实例与客户端的服务代理之间的关联方式.WCF具有单调(Per-Call).会话(Per-Session).和单例(Single) 单调(Per-Call) [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] public class TestService : ITest 会话(Per-Session) [ServiceBe

行为型模式--解释器模式

解释器模式 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式.这种模式实现了一个表达式接口,该接口解释一个特定的上下文.这种模式被用在SQL解析.符号处理引擎等. 介绍 意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子. 主要解决:对于一些固定文法构建一个解释句子的解释器. 何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子.这样就可以构建一个解释器,该解

专用服务器模式&amp;共享服务器模式

连接ORACLE服务器一般有两种方式:专用服务器连接(dedicated server)和共享服务器连接(shared server).那么两者有啥区别和不同呢?下面我们将对这两者的区别与不同一一剖析. 专用服务器模式(dedicated server)模式 在专用服务器模式中,用户进程运行在客户端的机器上,专用服务器进程运行在数据库服务器,用户进程和专用服务器进程是两种不同类型的进程. 对于专用服务器模式,在用户登录时,ORACLE总会创建一个新的服务进程,这通常称为专用服务器配置.这个服务器