一、服务实例的生命周期概览

我们已经直到,通过显式调用Close方法或等待默认的超时时间到来,都可以释放服务实例。但是,在会话连接里,经常需要按一定顺序调用方法。

二、分步操作

会话契约的操作有时隐含了操作调用的顺序。WCF提供了一种被称之为分步操作(Demarcating Operation)的方法,以应对服务契约的操作需要指定执行顺序的情况。分步操作是使用OperationContract特性的IsInitiating和IsTerminating属性:

[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationContractAttribute : Attribute
{
public bool IsInitiating
{get;set;}
public bool IsTerminating
{get;set;}
//More members
} 

IsInitiating属性的默认值为true,IsTerminating属性的默认的属性值则为false,对这些属性设置值会影响生成的WSDL文档。所以以下两个定义是等效的:

 [ServiceContract]public interface IService5{[OperationContract]void MyMethod();[OperationContract(IsInitiating=true,IsTerminating=false)]void MyMethod();}

默认情况下,操作不能划分会话的执行顺序。调用操作的顺序可以是最先、最后,也可以在会话中其它操作之间。使用属性的非默认值可以指定一个方法不被最先调用,或被最后调用,或者同时符合两个约束条件。

[ServiceContract(SessionMode = SessionMode.Required)]
interface IOrderManager
{[OperationContract]void SetCustomerId(int customerId);[OperationContract(IsInitiating = false)]void AddItem(int itemId);[OperationContract(IsInitiating = false)]decimal GetTotal(  );[OperationContract(IsInitiating = false,IsTerminating = true)]bool ProcessOrders(  );
}

此时,操作AddItem()、GetTotal()以及ProcessOrder()都不能是启动会话的第一个操作。同时,ProcessOrder()操作则会成为终止会话的操作。这与业务的要求是一脉相承的。

如果IsInitiating值为true(默认值),并不必然代表该操作必然是启动会话的第一个操作。如果其它相同设置的操作首先被调用,就会启动一个会话,而该操作则在被调用时才加入会话,成为会话的一部分;如果IsInitiating值为false,那就意味着在新的会话中该操作绝对不能作为第一个操作被客户端调用,同时,该方法只能在被调用时才加入会话,成为会话的一部分。

如果IsTermination的值为true,则代表该操作必须是终止会话的操作,然后以异步的方式释放服务实例。此时,客户端不能通过代理发出另外的调用。注意,客户端仍然应该关闭代理。虽然在服务契约定义时,允许将多个操作的IsTerminating值设置为true,但一旦调用了IsTerminating值为true的方法,就不能再调用服务实例的其它方法,除非在客户端重新创建一个代理对象。

三、实例停止

实例停用只针对会话服务而言。单例服务虽然也可以应用,但却无效。

迄今为止描述的会话服务的实例管理技术能够将一个客户端(多个客户端)连接到服务实例上。然而,真正的情形却复杂得多。先前提到过,每个服务实例都被托管在上下文中,如下图所示:

会话实际要做的不仅是关联客户端消息,同时还要关联托管了服务的上下文。启动宿主会创建一个新的上下文。会话终止时,上下文也随之终止。默认情况下,上下文的生命周期与发布的服务实例的生命周期相同。然而,出于优化和可扩展性的目的,WCF设计者提供了一种分离两种生命周期的选项,该选项允许WCF独立地停止实例,而不必依赖于它的上下文。实际上,WCF还允许不包含实例的上下文存在,如上图所示,我们将这种管理技术称为上下文停止。控制上下文停止的最常见办法是通过设置OperationBehavior特性的ReleaseInstanceMode属性。

public enum ReleaseInstanceMode
{None,BeforeCall,AfterCall,BeforeAndAfterCall,
}
[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationBehaviorAttribute : Attribute,...
{public ReleaseInstanceMode ReleaseInstanceMode{get;set;}//More members
}

ReleaseInstanceMode属性属于ReleaseInstanceMode枚举类型,其值代表了释放与方法相关的实例的时间:调用前,调用后、调用前与调用后,以及调用中。释放实例时,如果服务支持IDisposable接口,则还要停止Dispose()方法,并且Dispose()方法会拥有一个操作上下文。

通常,只需要将实例停止应用到部分(而不是全部)服务方法上,或者为不同的方法设置不同的值。

class MyService : IMyContract,IDisposable
{[OperationBehavior(ReleaseInstanceMode = ReleaseInstanceMode.AfterCall)]public void MyMethod(  ){...}public void MyOtherMethod(  ){...}public void Dispose(  ){...}
}

配置为ReleaseInstanceMode.None

ReleaseInstanceMode属性的默认值为ReleaseInstanceMode.None。

ReleaseInstanceMode.None意味着实例的生命周期不收调用的影响,如下图所示:

配置为ReleaseInstanceMode.BeforeCall

当方法被配置为配置为ReleaseInstanceMode.None时,如果会话已经存在一个实例,那么在转发调用之前WCF会停止实例,创建一个新的实例取代它,并让这个新的实例维护所要转发的调用,如下图所示:

ReleaseInstanceMode.BeforeCall可以用于优化诸如Create()这样的方法,用这些方法能够获取一些有价值的资源,并且释放原先分配的支援。启动会话时不需要获取资源,而应该等待,直到调用Create()方法,然后释放原先分配的资源,同时获取新的资源。在调用Create方法之后,就应该i准备启动对实例上的其它被配置成ReleaseInstanceMode.None方法的调用。

配置为ReleaseInstanceMode.AfterCall

当方法被配置为配置为ReleaseInstanceMode.AfterCall时,WCF会在调用方法之后停止实例,如下图所示:

这样设计可以优化诸如Cleanup()这样的方法,该方法能够清除实例所持有的有价值的资源,而不需要等到会话结束。通常都会在配置为ReleaseInstanceMode.None方法之后应用ReleaseInstanceMode.AfterCall的方法。

配置为ReleaseInstanceMode.BeforeAndAfterCall

当方法配置为ReleaseInstanceMode.BeforeAndAfterCall时,它结合了ReleaseInstanceMode.BeforeCall和ReleaseInstanceMode.AfterCall的功能。在执行调用之前,如果上下文包含一个实例,那么WCF就会调用前停止实例,再创建一个新的实例去维护调用,然后在调用后停止这个新创建的实例,如下图所示:

显式停止

除了可以通过应用OperationBehaviorAttribute应用ReleaseInstanceMode,也可以通过编程方式在服务的操作中显式地完成对实例的停止。方法是利用InstanceContext的ReleaseServiceInstance()方法:

class MyService : IMyContract,IDisposable
{public void MyMethod(  ){//Do some work thenOperationContext.Current.InstanceContext.ReleaseServiceInstance(  );}public void Dispose(  ){...}
}

这两种实现实例停止的方式还可以结合使用,例如在应用了OperationBehavior特性,并将ReleaseInstanceMode设置为 BeforeCall的方法中,如果显式调用ReleaseServiceInstance()方法,其效果就相当于将 ReleaseInstanceMode设置为BeforeAndAfterCall。

实例停止同样能够影响到单例服务。虽然服务允许这样的定义,但试图停止单例对象的方式是不可取的。

使用实例停止

实例停止是一种优化技术,通常情况下应该尽量避免使用它。只有在无法同时满足系统的性能要求和可伸缩性要求时,才考虑使用实例停止。

[WCF编程]8.服务实例的生命周期相关推荐

  1. Vue实例的生命周期

    vue实例的生命周期 什么是生命周期:从Vue实例创建.运行.到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期! 生命周期钩子:就是生命周期事件的别名而已: 生命周期钩子 = 生命周期函 ...

  2. vue 加载时掉用mounted_Vue实例中生命周期created和mounted的区别详解

    前言 本文主要跟大家介绍了关于Vue实例中生命周期created和mounted区别的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 生命周期先上图 什么是生命周期 Vue ...

  3. 神策数据张涛:企业服务客户全生命周期运营三步曲:执行反馈

    本文根据神策数据副总裁张涛关于企业服务客户全生命周期系列的直播内容整理,共 3 篇,本篇主要内容如下: 解决方案的落地与执行 解决方案执行效果反馈与分析 反向检验关键问题和解决方案的有效性 全生命周期 ...

  4. PPT 下载 | 神策数据张涛:企业服务客户全生命周期运营三步曲客情诊断 解决方案库...

    本文根据神策数据副总裁张涛关于企业服务客户全生命周期系列的直播内容整理,共 3 篇,上篇回顾<PPT 下载 | 神策数据张涛:企业服务客户全生命周期运营三步曲总览篇>,本篇主要内容如下: ...

  5. PPT 下载 | 神策数据张涛:企业服务客户全生命周期运营三步曲总览篇

    本文根据神策数据副总裁张涛关于企业服务客户全生命周期系列的直播内容整理,共 3 篇,本篇主要内容如下: 为什么要做企业服务客户全生命周期运营? 客户全生命周期运营存在哪些坑? 面对坑,企业该如何自救? ...

  6. 第五节:轻松掌握 vue 实例的生命周期

    公众号后台收到不少同学催更新,马上来. 上两节我们都是讲vue的实例,简单创建和定义实例的4个常用选项,没看过的伙伴可以先去看上两节,按顺序学习比较容易掌握. 这一节我们学习vue实例的生命周期,没错 ...

  7. java 实例的生命周期_[Java教程]Vue实例生命周期

    [Java教程]Vue实例生命周期 0 2017-08-15 19:00:09 前面的话 Vue实例在创建时有一系列的初始化步骤,例如建立数据观察,编译模板,创建数据绑定等.在此过程中,我们可以通过一 ...

  8. vue 请求在子组件加载后了_从零单排vue第九课--Vue实例及生命周期

    前期回顾 上一节课我们重点学习了子组件如何与父组件通信,我们使用$emit方法在子组件中触发一个事件,然后在父组件中接收它.本节课我们来深入了解下vue实例以及它的生命周期是怎么样的? 创建一个Vue ...

  9. Java并发编程|第二篇:线程生命周期

    文章目录 系列文章 1.线程的状态 2.线程生命周期 3.状态测试代码 4.线程终止 4.1 线程执行完成 4.2 interrupt 5.线程复位 5.1interrupted 5.2抛出异常 6. ...

最新文章

  1. javascript中new Date浏览器兼容性处理
  2. ubuntu dotnet core run 十月第一弹
  3. Java进阶:@FunctionalInterface函数式接口使用说明
  4. mybatis框架--学习笔记(上)
  5. 使用工具分析 SAP UI5 应用前端执行的性能问题
  6. linux脚本登录启动失败,linux-从bash脚本启动进程失败
  7. 阿里云上Kubernetes集群联邦 1
  8. harmonyos2.0测评,爆料:荣耀30 Pro开始测试华为鸿蒙HarmonyOS 2.0
  9. python里的π怎么调用_用python计算圆周率π
  10. VMware 虚拟化平台规划设计方案
  11. Android Framework内核之旅
  12. 【View】之【SimpleWaveView】可多色可刷新的加速球、进度球【demo】
  13. NXP IMX8系列应用处理器介绍
  14. 计算机单招知识点重点,2018年度单招考试《数学》必背知识点(一).doc
  15. Android中使用LitePal操控SQLite数据库
  16. hadoop 查看文件大小以及文件数
  17. php 分词搜索 splitword
  18. 腾讯云拟年内在全球增设超30%数据中心;Zepp Health首季成人智能手表出货量居全球前四 | 全球TMT...
  19. Jenkins自动化打包生成二维码下载链接
  20. 观点 | 电动汽车变革进行时,芯片IP供应商扮演着怎样的角色?

热门文章

  1. 解决filezilla中无法显示中文的文件名
  2. NPOI 读取excel到DataTable 读取隐藏列 读取公式列
  3. Response JSON数据返回
  4. Redis介绍及常用命令【转载】
  5. 1003. Parity(并查集)
  6. C#的Access数据库的连接类
  7. (03)两个模型的交集、并集、差集
  8. hhvm mysql_Ubuntu 14.10 安装 Nginx + MySQL + HHVM + phpMyAdmin [LNMH]
  9. airplay服务器linux,在Linux实现airplay
  10. html input type=quot;filequot;,input[type='file']默认样式