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提供的一些对于特殊需求的优化技术,通常情况下不必去可以使用它。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏轻量级微服务

微服务下跨语言 RPC 实现

目前主流的 Java 开发框架 Spring Boot,为了更方便集成 gRPC,自己开发了 spring-boot-starter-grpc,仅需简单的几行配...

1203
来自专栏前端杂货铺

由objC运行时所想到的。。。

objC语言不仅仅有着面向对象的特点(封装,继承和多态),也拥有类似脚本语言的灵活(运行时),这让objC有着很多奇特的功能-可在运行时添加给类或对象添加方法,...

3348
来自专栏龙渊阁测试精英

Jmeter(四)_16个逻辑控制器详解

1、 Jmeter官网对逻辑控制器的解释是:“Logic Controllers determine the order in which Samplers a...

1432
来自专栏java达人

Quartz作业调度框架

Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为...

1985
来自专栏晓晨的专栏

ASP.NET Core 中间件(Middleware)详解

1052
来自专栏Golang语言社区

GOLANG 中HTTP包默认路由匹配规则阅读笔记

一、执行流程 构建一个简单http server: package main import ( "log" "net/http" ) func main...

3696
来自专栏程序员叨叨叨

【转】使用 Spring HATEOAS 开发 REST 服务原文

绝大多数开发人员对于 REST 这个词都并不陌生。自从 2000 年 Roy Fielding 在其博士论文中创造出来这个词之后,REST 架构风格就很快地流行...

781
来自专栏偏前端工程师的驿站

Java魔法堂:URI、URL(含URL Protocol Handler)和URN

一、前言                                 过去一直搞不清什么是URI什么是URL,现在是时候好好弄清楚它们了!本文作为学习笔记,...

1855
来自专栏禹都一只猫博客

Flask RESTful API 简单的设计一个 GET 请求接口

3405
来自专栏屈定‘s Blog

Java8 Lambda(三)-强大的collect操作

collect应该说是Stream中最强大的终端操作了,使用其几乎能得到你想要的任意数据的聚合,下面好好分析该工具的用法.

1402

扫码关注云+社区