zoukankan      html  css  js  c++  java
  • 那些年,我们一起学WCF--(6)PerCall实例行为

    当客户端调用服务器端服务后,服务器端就会为客户端生成一个实例,关于服务实例的分配问题,在WCF中有专门的属性进行设置,可以让所有客户端共享一个实例,

    也可以让一个客户端可以拥有多个实例,也可以让一个实例只能被客户端使用一次。

           关于实例的分配和使用范围,在WCF通过服务行为的InstanceContextMode枚举进行设置.InstanceContextMode有三种枚举类型

               PerSession=0 会话实例,此为默认值

               PerCall=1  

               Single=2

          接下来我们看下这三种策略的使用方法

          1.PerCall实例

             PerCall实例策略是指WCF为每个客户端的每一次请求,都会生成一个新的服务实例,各个实例不会相互影响,客户端调用结束后,服务器端立刻销毁该实例.

             下面的这段代码演示了PerCall实例的实现,在服务器端的契约实现实现上用InstanceContextMode.PerCall标记为实例策略,

             服务器端契约实现每调用一次AddCount方法,变量num的值会加1,当客户调用方法执行完毕的时候,会通过Dispose方法释放当前实例。

             通过这个例子,我们可以看到,在客户端的服务代理调用两次AddCount方法,但是变量num的值没有改变,两次输出的值都是1       

    1. [ServiceContract] 
    2.    publicinterface IPerCall 
    3.    { 
    4.        [OperationContract] 
    5.        int AddCount(); 
    6.    } 
    7.  
    8.    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)] 
    9.    publicclass PerCallImpl:IPerCall,IDisposable 
    10.    { 
    11.        privateint num = 0; 
    12.        publicint AddCount() 
    13.        { 
    14.            num =num + 1; 
    15.            Console.WriteLine("当前值:"+num.ToString()+",时间:"+DateTime.Now.ToString()); 
    16.            return num; 
    17.        } 
    18.  
    19.        publicvoid Dispose() 
    20.        { 
    21.            Console.WriteLine("实例释放"); 
    22.            Console.WriteLine("---------"); 
    23.        } 
     [ServiceContract]
        public interface IPerCall
        {
            [OperationContract]
            int AddCount();
        }
    
        [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
        public class PerCallImpl:IPerCall,IDisposable
        {
            private int num = 0;
            public int AddCount()
            {
                num =num + 1;
                Console.WriteLine("当前值:"+num.ToString()+",时间:"+DateTime.Now.ToString());
                return num;
            }
    
            public void Dispose()
            {
                Console.WriteLine("实例释放");
                Console.WriteLine("---------");
            }

          启动服务器端,服务器端宿主是一个控制台应用程序

    1. ServiceHost host = new ServiceHost(typeof(PerCallImpl)); 
    2.           host.Open(); 
    3.           Console.WriteLine("服务器端启动..."); 
    4.           Console.ReadLine(); 
      ServiceHost host = new ServiceHost(typeof(PerCallImpl));
                host.Open();
                Console.WriteLine("服务器端启动...");
                Console.ReadLine();
    

       在客户端,我们生成一个服务器端实例,同一个实例,调用服务器端的同一个方法两次,计数器的结果是一样的。

    1. privatevoid button1_Click(object sender, EventArgs e) 
    2.      { 
    3.          ChannelFactory<IPerCall> channelFactory = new ChannelFactory<IPerCall>("WSHttpBinding_IPerCall"); 
    4.          IPerCall apple = channelFactory.CreateChannel(); 
    5.          //同一个客户端实例调用AddCount方法两次,输出的结果一样 
    6.          apple.AddCount(); 
    7.          apple.AddCount(); 
    8.      } 
       private void button1_Click(object sender, EventArgs e)
            {
                ChannelFactory<IPerCall> channelFactory = new ChannelFactory<IPerCall>("WSHttpBinding_IPerCall");
                IPerCall apple = channelFactory.CreateChannel();
                //同一个客户端实例调用AddCount方法两次,输出的结果一样
                apple.AddCount();
                apple.AddCount();
            }

        效果图:

         

                  通过这个例子,我们可以看到PerCall的优缺点

             1.客户端每发送一次请求,服务器都会生成一个新的服务实例,各个服务实例不会相互影响,每次调用都可以看作一个单独的线程,不用考虑线程冲突的问题。不会产生并发性.

             2.服务器端在客户端调用完毕后,就立刻释放服务实例,这样提高了服务器的使用率,在不用的时候立刻被释放,增加了系统的吞吐量,提高了服务器的使用率.

          缺点:

            假设我们要从数据库查询大数据量数据,每次调用查询的数据都是一样的,这是一个很耗时的过程,如果使用PerCall模式每次调用服务器端的方法都要查询一次数据,这样就增加了调用执行时间,客户端等待的时间就会过长,影响了客户端执行效率。这时候PerCall模式的弊端就暴露出来了,两次查询的数据不能共享。

       对于这种问题,我们可以采用缓存进行解决,也可以使用其他实例行为进行解决,在下节我们看下其他实例行为。

        demo下载:http://download.csdn.net/detail/zx13525079024/4596356

  • 相关阅读:
    转自:stuff字符串拼接方法
    mssql sqlserver in 关键字在值为null的应用举例
    mssql sqlserver 将字段null(空值)值替换为指定值的三种方法分享
    mssql sqlserver 使用sql脚本输出交替不同的背景色的html信息的方法分享
    MSSQL coalesce系统函数简介
    MSSQL sql server order by 1,2 的具体含义
    JavaScript正则表达式模式匹配(1)——基本字符匹配
    正则表达式的语法和使用说明
    log4j日志的基本使用方法(1)——概述、配置文件
    写在博客园开博第一篇博文
  • 原文地址:https://www.cnblogs.com/gjhjoy/p/3487370.html
Copyright © 2011-2022 走看看