现在的位置: 首页 > 综合 > 正文

那些年,我们一起学WCF–(6)PerCall实例行为

2013年10月11日 ⁄ 综合 ⁄ 共 1961字 ⁄ 字号 评论关闭

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

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

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

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

           PerCall=1  

           Single=2

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

      1.PerCall实例

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

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

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

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

 [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("---------");
        }

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

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

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

   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

抱歉!评论已关闭.