通过WCF的ServiceBehaviorAttribute设定InstanceContextMode有下面的3中模式: 
1. Single —— 表示所有的客户端共享一个会话(服务对象)(服务关闭时才会销毁服务对象) 
2. PerCall —— 表示每次调用都会创建一个会话(服务对象)(调用完毕后就会销毁服务对象) 
3. PerSession —— 表示为每个连接(每个客户端代理对象) 创建一个会话(服务对象),只有指定IsTerminating=true的操作被调用,或者是设定的SessionTimeout超时的时候,服务对象会被销毁。但支持Session的Binding只有:WSHttpBinding、WSDualHttpBinding、WSFederationHttpBinding、NetTcpBinding。

测试一下上述行为,设计3个Service,每个Service都在构造函数中输出内容并实现IDispose接口,在Dispose()里输出内容。 
(准备) Host实现代码:

  1. static void Main(string[] args)
  2. {
  3. ServiceHost host1 = new ServiceHost(typeof(SingleService));
  4. host1.Open();
  5. Console.WriteLine("SingleService Opened!");
  6. ServiceHost host2 = new ServiceHost(typeof(PeerCallService));
  7. host2.Open();
  8. Console.WriteLine("PeerCallService Opened!");
  9. ServiceHost host3 = new ServiceHost(typeof(PeerSessionService));
  10. host3.Open();
  11. Console.WriteLine("PeerSessionService Opened!");
  12. Console.Read();
  13. }

(一) Single服务契约——服务端启动时实例化

 

  1. [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
  2. public class SingleService : IService1, IDisposable
  3. {
  4. public SingleService()
  5. {
  6. Console.WriteLine("SingleService ({0}) [{1:mm:ss.fff}] ctor", this.GetHashCode(), DateTime.Now);
  7. }
  8. public string GetData(string value)
  9. {
  10. return string.Format("SingleService ({0}) GetData [{1}]", this.GetHashCode(), value);
  11. }
  12. public void Dispose()
  13. {
  14. Console.WriteLine("SingleService ({0}) [{1:mm:ss.fff}] dispose", this.GetHashCode(), DateTime.Now);
  15. }
  16. }


启动Host调用SingleService.GetData,服务端的输出:

上图说明SingleService在服务启动时就创建了。

(二) PerCall服务契约——每次调用都重新实例化

  1. [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
  2. public class PeerCallService : IService1, IDisposable
  3. {
  4. public PeerCallService()
  5. {
  6. Console.WriteLine("PeerCallService ({0}) [{1:mm:ss.fff}] ctor", this.GetHashCode(), DateTime.Now);
  7. }
  8. public string GetData(string value)
  9. {
  10. return string.Format("PeerCallService ({0}) GetData [{1}]", this.GetHashCode(), value);
  11. }
  12. public void Dispose()
  13. {
  14. Console.WriteLine("PeerCallService ({0}) [{1:mm:ss.fff}] dispose", this.GetHashCode(), DateTime.Now);
  15. }
  16. }


调用PeerCallService.GetData

(三) PerSession服务契约——客户端第一次调用时实例化

  1. [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
  2. public class PeerSessionService : IService1, IDisposable
  3. {
  4. public PeerSessionService()
  5. {
  6. Console.WriteLine("PeerSessionService ({0}) [{1:mm:ss.fff}] ctor", this.GetHashCode(), DateTime.Now);
  7. }
  8. public string GetData(string value)
  9. {
  10. return string.Format("PeerSessionService ({0}) GetData [{1}]", this.GetHashCode(), value);
  11. }
  12. public void Dispose()
  13. {
  14. Console.WriteLine("PeerSessionService ({0}) [{1:mm:ss.fff}] dispose", this.GetHashCode(), DateTime.Now);
  15. }
  16. }

服务端的Session的Timeout是由binding属性receiveTimeout和inactivityTimeout控制的。

  1. <bindings>  
  2.   <wsHttpBinding>  
  3.     <binding name="wsHttp" receiveTimeout="00:00:15">  
  4.       <reliableSession enabled="true"  inactivityTimeout="00:00:15" />  
  5.     </binding>  
  6.   </wsHttpBinding>  
  7. </bindings>  

关于这两个属性的配置,更详细的说明请参考MSDN,按照配置服务对象在客户端没有调用后15秒销毁:

需要注意的是,每次 new WcfSvcPeerSession.Service1Client() 都是一个新的Session。

接下来看看怎么通过 OperationContact 的 IsInitiating 和 IsTerminating 来控制Session。IsInitiating 表示该方法是否可以初始化 Session,IsTerminating 表示该方法是否可以终止 Session。默认设置 IsInitiating=true,IsTerminating=false。另外通过IsInitiating和IsTerminating 控制的时候,必须设置 ServiceContract 的 SessionMode.Required 
服务契约的定义

  1. [ServiceContract(SessionMode = SessionMode.Required)]
  2. interface IService2
  3. {
  4. [OperationContract(IsInitiating=true)]
  5. void LogIn();
  6. [OperationContract]
  7. void DoSth();
  8. [OperationContract(IsTerminating=true)]
  9. void LogOff();
  10. }

服务契约的实现:

  1. public class PeerSessionService2 : IService2
  2. {
  3. public void LogIn()
  4. {
  5. var sessionId = OperationContext.Current.SessionId;
  6. Console.WriteLine("{0} LogIn.", sessionId);
  7. }
  8. public void DoSth()
  9. {
  10. var sessionId = OperationContext.Current.SessionId;
  11. Console.WriteLine("{0} DoSth.", sessionId);
  12. }
  13. public void LogOff()
  14. {
  15. var sessionId = OperationContext.Current.SessionId;
  16. Console.WriteLine("{0} LogOff.", sessionId);
  17. }
  18. }

一旦LogOff即IsTerminating,Session就结束了。再次调用任何服务端方法都会引发异常。

WCF 学习总结3 -- 实例模式的更多相关文章

  1. WCF服务类的实例模式(本文为转载)

    WCF开发时如何选择正确的实例模式(InstanceMode)?   在使用WCF实例模型时,你是否思考过这几个的问题: ”WCF中的实例模式如何正确应用”? ”使用WCF中的实例模式有何原则可以遵循 ...

  2. WCF学习之旅—TCP双工模式(二十一)

    WCF学习之旅—请求与答复模式和单向模式(十九) WCF学习之旅—HTTP双工模式(二十) 五.TCP双工模式 上一篇文章中我们学习了HTTP的双工模式,我们今天就学习一下TCP的双工模式. 在一个基 ...

  3. WCF学习之旅—HTTP双工模式(二十)

    WCF学习之旅—请求与答复模式和单向模式(十九) 四.HTTP双工模式 双工模式建立在上文所实现的两种模式的基础之上,实现客户端与服务端相互调用:前面介绍的两种方法只是在客户端调用服务端的方法,然后服 ...

  4. WCF并发控制与实例模式

    WCF实例模式类型与区别 实例化模式 instanceMode percall        单调模式 [ServiceBehavior(InstanceContextMode=InstanceCon ...

  5. WCF开发时如何选择正确的实例模式(InstanceMode)?

    WCF开发时如何选择正确的实例模式(InstanceMode)?   在使用WCF实例模型时,你是否思考过这几个的问题: ”WCF中的实例模式如何正确应用”? ”使用WCF中的实例模式有何原则可以遵循 ...

  6. WCF学习笔记之传输安全

    WCF学习笔记之传输安全 最近学习[WCF全面解析]下册的知识,针对传输安全的内容做一个简单的记录,这边只是简单的记录一些要点:本文的内容均来自[WCF全面解析]下册: WCF的传输安全主要涉及认证. ...

  7. WCF学习之旅——第一个WCF示例(一)

    最近需要用到WCF,所以对WCF进行了解.在实践中学习新知识是最快的,接下来先做了一个简单的WCF服用应用示例. 本文的WCF服务应用功能很简单,却涵盖了一个完整WCF应用的基本结构.希望本文能对那些 ...

  8. WCF学习之旅——第一个WCF示例(二)

    第四步:通过自我寄宿的方式寄宿服务 WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程.WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段. 终 ...

  9. WCF会话(Session)与实例(Instance)管理

    一.理解Session 1.Session的作用:保留Client和Service之间交互的状态,确保Client与Service之间交互唯一性(SessionId),即:多个Client同时访问Se ...

随机推荐

  1. 为cocos2d-x实现安卓输入框。非全屏,无dialog,绑定到lua

    cocos2d-x官方自带的输入框,简直惨不忍睹,在ios还好,在安卓简直了..用过的都知道... 所以为了用户体验,我们自己搞一个吧.输入框这种东西比较特殊,不像按钮.列表框之类的很容易实现,因为涉 ...

  2. Python socket模拟HTTP请求

    0x00 起 最近在做一个对时间要求比较高的扫描器,需要封装一下SOCKET模拟HTTP发包的一些常用函数.简单的说,就是重写一下requests中的get.post方法. 今天在写的时候,遇到一枚很 ...

  3. 关于mapreduce过程中出现的错误:Too many fetch-failures

    Reduce task启动后第一个阶段是shuffle,即向map端fetch数据.每次fetch都可能因为connect超时,read超时,checksum错误等原因而失败.Reduce task为 ...

  4. Many To one 多对一

    一.创建实体类:多方存一方的对象.set/get 二.编写对象的xml文件 别忘记在confg.xml映射! 三.编写接口 四.方法测试

  5. 3D游戏常用技巧Normal Mapping (法线贴图)原理解析——高级篇

    1.概述 上一篇博客,3D游戏常用技巧Normal Mapping (法线贴图)原理解析——基础篇,讲了法线贴图的基本概念和使用方法.而法线贴图和一般的纹理贴图一样,都需要进行压缩,也需要生成mipm ...

  6. 山东省第四届ACM大学生程序设计竞赛解题报告(部分)

    2013年"浪潮杯"山东省第四届ACM大学生程序设计竞赛排名:http://acm.upc.edu.cn/ranklist/ 一.第J题坑爹大水题,模拟一下就行了 J:Contes ...

  7. 常用脚本语言Perl,Python,Ruby,Javascript一 Perl,Python,Ruby,Javascript

    常用脚本语言Perl,Python,Ruby,Javascript一 Perl,Python,Ruby,Javascript Javascript现阶段还不适合用来做独立开发,它的天下还是在web应用 ...

  8. 1048: [HAOI2007]分割矩阵 - BZOJ

    Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了 ...

  9. C#取中间文本

    /// <summary> /// 取中间文本 + static string GetMiddleStr(string oldStr,string preStr,string nextSt ...

  10. sql不重复的查找统计数据(经典)

    例表如下: 表名:MYTEST TID    COL1    COL2     COL3 1           1           A            A2           1     ...