[WCF编程]8.服务实例的生命周期
一、服务实例的生命周期概览
我们已经直到,通过显式调用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 then
OperationContext.Current.InstanceContext.ReleaseServiceInstance( );
}
public void Dispose( )
{...}
}这两种实现实例停止的方式还可以结合使用,例如在应用了OperationBehavior特性,并将ReleaseInstanceMode设置为 BeforeCall的方法中,如果显式调用ReleaseServiceInstance()方法,其效果就相当于将 ReleaseInstanceMode设置为BeforeAndAfterCall。
实例停止同样能够影响到单例服务。虽然服务允许这样的定义,但试图停止单例对象的方式是不可取的。
使用实例停止
实例停止是一种优化技术,通常情况下应该尽量避免使用它。只有在无法同时满足系统的性能要求和可伸缩性要求时,才考虑使用实例停止。
[WCF编程]8.服务实例的生命周期的更多相关文章
- [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期
生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...
- 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)
一.Vue的实例 1.1.创建一个 Vue 的实例 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项 }) 虽然没有完全遵循 ...
- Vue.js 1.x 和 2.x 实例的生命周期
在Vue.js中,在实例化Vue之前,它们都是以HTML的文本形式存在文本编辑器中.当实例化后将经历创建.编译.销毁三个主要阶段. 以下是Vue.js 1.x 实例的生命周期图示: Vue.js 1 ...
- Vue.js-07:第七章 - Vue 实例的生命周期
一.前言 在之前的 Vue 学习中,我们在使用 Vue 时,都会创建一个 Vue 的实例,而每个 Vue 实例在被创建时都要经过一系列的初始化过程.例如,需要设置数据监听.编译模板.将实例挂载到 D ...
- Vue2.5笔记:Vue的实例与生命周期
理解与认识 Vue 的实例是我们学习 Vue 非常重要的一步,也是非常必须的,因为实例是它的一个起点,也是它的一个入口,只有我们创建一个 Vue 实例之后,我们才行利用它进行一些列的操作. 首先 Vu ...
- vue实例的生命周期
Vue实例的生命周期也就是这个实例从出生到死亡的过程,所以我在文档原图上把这个周期大致分为创建过程 | 运行过程 | 销毁过程三个阶段,不同结果或又分为一些小的阶段 在第一个阶段,创建阶段,会完成Vu ...
- 浅析vue实例的生命周期(生命周期钩子)
“每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等” ,在不同的生命周期内会经历不同的钩子函数(生命周期 ...
- 从零开始学 Web 之 Vue.js(三)Vue实例的生命周期
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)
昨日内容回顾 0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue ...
随机推荐
- Linux的原子操作与同步机制
Linux的原子操作与同步机制 .进程1执行完“mov eax, [count]”后,寄存器eax内保存了count的值0.此时,进程2被调度执行,抢占了进程1的CPU的控制权.进程2执行“cou ...
- 非正规方法处理AngulurJS模块管理问题
1.起因 自己一直做winform,有幸从某个大神手里接了一个node.js,express,angulurJS等集众多开源框架的一个项目,赶鸭子上架,于是一边学习,一边用自己以往的思中去整理,重构代 ...
- Understanding RabbitMQ Exchange & Queue
Exchanges are the only places where messages could be published to; while queues are the only places ...
- Atitit 深入理解软件的本质 attilax总结 软件三原则"三次原则"是DRY原则和YAGNI原则的折
Atitit 深入理解软件的本质 attilax总结 软件三原则"三次原则"是DRY原则和YAGNI原则的折 1.1.1. 软件的本质:抽象 1 1.2. 软件开发的过程就是不断 ...
- iOS—Xcode 7真机测试
Xcode 7真机测试详解 1.准备 注意:一定要让你的真机设备的系统版本和app的系统版本想对应,如果不对应就会出现一个很常见的问题:could not find developer disk im ...
- HTML 最简单的tips 怎么支持指定DIV显示提示信息
<body> <style type="text/css"> a.link{position:relative;} a.link div.tips{ bor ...
- Windows中搭建Redis集群
从 http://rubyinstaller.org/downloads/ 下载Ruby2.2.5(x64)并安装,安装时勾选添加至路径变量中 命令行中执行gem source -a http://g ...
- [转]Linux常用命令
系统信息arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / ...
- 【Win 10应用开发】多窗口视图
Windows App一般情况下,同一时刻只能有一个应用程序实例在运行,为了在特殊需求下可以同时呈现不同的UI,SDK提供了多视图操作支持. 应用程序可以创建新的应用视图,以新的视图为基础可以呈现与主 ...
- WPF开发查询加班小工具
先说一下,我们公司是六点下班,超过7点开始算加班,但是加班的时间是从六点开始计算,以0.5个小时为计数,就是你到了六点半,不算加班半小时,但是加班到七点半,就是加班了一个半小时. 一.打卡记录 首先, ...




