WCF中操作的分界于调用顺序和会话的释放操作分界实例停止
操作分界
在WCF操作契约的设计中,有时会有一些调用顺序的业务,有的操作不能最先调用,有的操作必须最后调用,比如在从一个箱子里拿出一件东西的时候,必须先要执行打开箱子的操作,而关上箱子的操作应该在一切工作完成之后再被执行。
public interface Box
{
void Open(int boxId);
int GetTotalFrenchletter();
void Close();
}
为了解决这种实际需求,WCF在OperationContractAttribute中提供了IsInitiating和IsTerminating属性,IsInitiating的默认值为true,表示当前操作可以被第一个调用,IsTerminating属性默认为false,表示在这个方法执行完之后,服务对象不会被释放。可以通过这两个属性来控制上文中提供的需求。
此外,在修改了默认值之后,在装在服务的时候,WCF会去验证服务契约是否被定义为SessionMode.Required,如果不是,WCF会抛出InvalidOperationExample异常。
上文中的契约定义可以被重新设计:
[ServiceContract(SessionMode=SessionMode.Required)]
public interface Box
{
[OperationContract(IsInitiating=true,IsTerminating=false)]
void Open(int boxId);
[OperationContract(IsInitiating = false, IsTerminating = false)]
int GetTotalFrenchletter();
[OperationContract(IsInitiating = false, IsTerminating = true)]
void Close();
}
Open方法上的Attribute和不去添加它是一样的含义,只不过看起来更加清晰一点
有一点需要注意的是,参照以上的契约定义,在Close调用执行完之后,WCF会异步的释放对象并且关闭会话,客户端将不能再通过当前代理调用服务中的操作。
实例停止
在服务的生命周期中,上下文是一直伴随着服务实例的创建于释放的整个过程的,然后处于某些目的,WCF也提供了分离两者的选项,允许服务实例被单独的停止。方法就是设置OperationBehaviorAttribute的ReleaseInstanceMode属性,它是一个名为ReleaseInstanceMode的枚举类型,包含了AfterCall、BeforeCall、BeforeAndAfterCall和None四个值,默认值为None。
BeforeCall:将在调用当前操作之前,WCF会释放当前的服务实例,然后创建一个新的实例取代它,然后在这个新的实例上调用方法;
AfterCall:将在调用当前操作之后释放当前服务实例;
BefireAndAfterCall:它是对前两种设置的一种补充,OperationBehavior如果应用了这个值,那么当前方法可以在标记了BeforeCall或者None的方法之后调用,也可以在在标记了AfterCall或者None的方法之后调用.
而在上文中的示例中,我们可以做如下的定义
public class Box : IBox
{
public void Open(int boxId)
{
throw new NotImplementedException();
}
public int GetTotalFrenchletter()
{
throw new NotImplementedException();
}
[OperationBehavior(ReleaseInstanceMode=ReleaseInstanceMode.AfterCall)]
public void Close()
{
lockBox();
}
}
即使如此,WCF仍然提供了一个直接停止服务实例的方法,以满足在以上设置中都没有找到一个完美的适用于您的需求的解决方案。然后再非不得已的情况下,应该尽量不要使用它,因为它破坏了业务逻辑和服务本身生命周期的分离。
方法很简单,在OperationContext中存在InstanceContext,而这个属性包含一个ReleaseServiceInstance方法,在这个方法调用之后服务将会被释放:
[OperationBehavior(ReleaseInstanceMode=ReleaseInstanceMode.AfterCall)]
public void Close()
{
lockBox();
OperationContext.Current.InstanceContext.ReleaseServiceInstance();
}
然后,以上所述的技术,仅仅是WCF提供的一些对于特殊需求的优化技术,通常情况下不必去可以使用它。
- ExecuteReader在执行有输出参数的存储过程时拿不到输出参数
- CTF---Web入门第十三题 拐弯抹角
- 小案例(四):销售额下滑(python)
- 【最新TensorFlow1.4.0教程01】TF1.4.0介绍与动态图机制 Eager Execution使用
- 把插入的数据自动备份到另一个表中 ~ 语境:本地和服务器自动同步
- 数据分析小案例(三):调查问卷(python)
- CTF---Web入门第十六题 天下武功唯快不破
- 数据分析小案例(二):面包是不是变轻了(python)
- 数据分析小案例(一):商业街抽奖(python)
- Bagging算法(R语言)
- iOS @property探究(一): 基础详解你要知道的@property都在这里
- 在创建带输出参数和返回值的存储过程时---犯下的一个低级错误
- iOS block探究(二): 深入理解你要知道的block都在这里
- 使用开源人脸特征提取器进行脸部颜值评分
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 听说Mysql你很豪横?-------------呕心沥血深入解析mysql备份与恢复!!!
- 排障集锦:九九八十一难之第十难!mysq备份恢复,Could not read entry at offset *: Error in log format or read error.
- Vue使用ref父子组件通信
- 听说Mysql你很豪横?-------------MySQL5.7主从同步
- 听说Mysql你很豪横?-------------MySQL5.7主从复制!读写分离!
- Vue兄弟组件传值
- Vue设置浏览器的标题title和图标icon
- VantUI封装自定义Tabbar路由跳转
- 听说Mysql你很豪横?-------------分分钟带你玩转SQL高级查询语句(常用查询,正则表达式,运算符)
- jQuery实现点击添加样式同胞移除样式
- 微信小程序生命周期
- 听说Mysql你很豪横?-------------分分钟带你玩转SQL高级查询语句(库函数,存储过程)
- 微信小程序下拉刷新上拉加载
- 微信小程序引用自定义组件
- 听说Mysql你很豪横?-------------搭建MySQL MHA实现数据库高可用( MySQL MHA概述、 搭建 MySQL MHA、 MySQL MHA 故障切换)