zoukankan      html  css  js  c++  java
  • 实例上下文模式:单调模式

        在创建一个服务端的时候都会依托于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
        {.....}
    
  • 相关阅读:
    (华中科大)江南雨烟 C++ STL 专栏
    MoreWindows 微软认证专家博客目录(白话算法,C++ STL,windows编程)
    「转」基于Jmeter和Jenkins搭建性能测试框架
    【转】docker之Dockerfile实践
    Python 统一动态创建多个model对应的modelForm类(type()函数)
    owasp zap 安全审计工具 安装/拦截请求
    【转】持续集成 Sonar 平台搭建及 Sonar 自定义规则打包部署篇
    【转】SonarQube配置自定义的CheckStyle代码规则
    【转+整理】jenkins与SonarQube集成
    【转】jenkins插件pipeline使用介绍
  • 原文地址:https://www.cnblogs.com/lh218/p/4532178.html
Copyright © 2011-2022 走看看