注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

WCF的学习总结(五)——SESSION的使用  

2011-08-22 16:25:24|  分类: NET(C#) |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

WCF的学习总结(五)--SESSION的使用
自己的机器上没有装IIS,装也装不上,又没时间重装系统,只好把IIS的部分先略过,有时间再整他,我们说说SESSION,在WEB中,SESSION是在页面间共享变量的一个方法,不过这个东西很耗资源,一般不推荐在这个里面长时间的使用较大的变量的。
一、默认的Instance Context Model
在WCF中,也有SESSION之说,一般来说,basicHttpBinding默认的情况下是不支持SESSION,不支持的结果就是调用不会成功,但也不会报什么错误,所以要改做wsHttpBinding这种绑定方式,为了监视运行的情况,在服务类中增加:
        public SessionCalculator()
        {
            Console.WriteLine("SessionCalculator construct function!!!");
        }
        ~SessionCalculator()
        {
            Console.WriteLine("Calculator object has been destoried");
        }
结果发现,构造函数被调用了,但是析构函数没有调用,说明客户端和服务端的实例都仍然在内存中存在。于是,可以用:(proxy1 as ICommunicationObject).Close();来强制的释放代理。然后在重新调用时发现,析构函数被调用了。为了测试SESSION,可以在服务的接口类中,显式的使用SessionMode.NotAllowed模式。
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
    public interface ICalculator
    {
        /// <summary>
        /// add fun
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [OperationContract(IsOneWay=true)]
        void Add(double x);
        [OperationContract]
        double GetResult();
    }
那么输出的结果不用想,和不支持的basicHttpBinding产生的现象是一样的。由此可以得出,服务端是采用PerCall的Instance Context Model。如果强制的将SESSION设为需求,并进行如下设定:
    [ServiceContract(SessionMode=SessionMode.Required)]
    public interface ICalculator
    {
        /// <summary>
        /// add fun
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [OperationContract(IsOneWay=true, IsInitiating=true,IsTerminating=false)]
        void Add(double x);
        [OperationContract(IsInitiating=false,IsTerminating=true )]
        double GetResult();
    }
会产生什么现象呢?
修改一下客户端,增加如下代码:
            try
            {
                proxy1.Adds(1);
            }
            catch (Exception ex)
            {
                Console.WriteLine("It is fail to invocate the Add after terminating session because \"{0}\"", ex.Message);
            }
运行起来发现,程序抛出了一个异常,因为在GetResult函数中,显式的声明了调用这个函数后SESSION终止。于是再调用,SESSION没有了,其对应的实例也被标识为可以回收。这时候再调用其,便是不允许的,因此只能抛出一个异常来。

二、默认显示支持SESSION
将服务的实体类改为如下:
    //[ServiceBehavior(InstanceContextMode =  InstanceContextMode.PerCall)]
    //[ServiceBehavior(InstanceContextMode =  InstanceContextModePerSession)]
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]//
注意这里
    public class SessionCalculator:ICalculator
    {//内容不变}
分别使用上面三种不同的Instance Context Mode可以得到不同的结果:
其中第一个是无法得到正确的现象的,因为其仍然是保持了每个代理的生命周期是和SESSION是一致的,由于创建了不同的服务实例,所以结果只能为0。
第二种达到设计的目的。
第三种因为是单实例,所以一直在累加,也就是说,无论多少调用其实都用的这一个,和第一种正好相反。
三、遇到的错误和小BUG:
1、app.config配置文件更改后,应该重新编译一次,虽然觉得不编译可以但发现报一个错,说什么服务端和客户商的数据不匹配。重新编译一次就OK了。
2、在客户端的配置文件中,如果对端点(endpoint)名字(name属性)进行了命名,而在代码中又绑定了这个名字, ChannelFactory<ICalculator> calculatorChannelFactory = new ChannelFactory<ICalculator>("httpEndpoint");那么二者一定要一致,否则,报错,找不到相应的端点。
越学发现需要学的东西越多,一定要认真,努力,不要懈怠。

  评论这张
 
阅读(1039)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017