[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 ...
随机推荐
- Java NIO6:选择器2---代码篇
选择器服务器端代码 上一篇文章毫无条理地讲了很多和选择器相关的知识点,下面进入实战,看一下如何写和使用选择器实现服务端Socket数据接收的程序,这也是NIO中最核心.最精华的部分. 看一下代码: p ...
- WPF+通过配置文件生成菜单(Menu)+源码
这个月做项目,遇到过一个通过配置文件来生成菜单的解决方案,感觉挺优雅的,特地放到博客园来,以飨读者. 说来惭愧,以前做的项目都没有这样用过,都是固定死了.如果后续有需要加入菜单,还得在重新修改UI,然 ...
- MySQL 远程连接(federated存储引擎)
标签:federated存储引擎 概述 本文主要介绍通过federated存储引擎建立远程连接表 测试环境:mysql 5.6.21 步骤 开启federated存储引擎 先查看federated存储 ...
- Silverlight和WPF中DataContractJsonSerializer对时间的处理差异
原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com Silverlight脱胎于WPF,他们的行为不完全并不完全相同,DataContractJsonSerializ ...
- C#设计模式之工厂
IronMan之工厂 前言 实用为主,学一些用得到的技术更能在如今的社会里保命. 虽然在日常的工作中设计模式不是经常的用到,但是呢,学习它只有好处没有坏处. 设计模式像是一种“标签”,它是代码编写者思 ...
- ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...
- TDR分辨率
在日常的生活工作中,有很多测试测量的工具,比如测量长度的尺子,计量时间的钟表等等,谈到测试测量工具的时候,分辨率是关键指标之一,比如尺子的 分辨率是1mm,时钟的分辨率是秒.所谓分辨率就是测试测量工具 ...
- js浏览器对象模型-BOM
bom browse object model 浏览器对象模型. 也就是window对象下面的东西. location 对象 window.location.href 表示打开窗口的路径. windo ...
- Redux
redux是Flux的一种实现方式,但还是和Flux有些不同. React控制视图层,要想做一个完整的数据流,必须要用react-redux. 官方demo,自己收集了一下: demo1http:// ...
- 判断checkbox的checked状态(jQuery写法)
$('#checkboxInput').click(function(){ if (this.checked){ $('.questionContainer').css({ "opacity ...