WCF开发时如何选择正确的实例模式(InstanceMode)?

 
在使用WCF实例模型时,你是否思考过这几个的问题:

”WCF中的实例模式如何正确应用”?
”使用WCF中的实例模式有何原则可以遵循吗”? 

众所周知:客户端调用服务时,最终会将调用服务端的某个实例来完成。在WCF服务中,可以通过ServiceBehavior的InstanceContextMode设置服务实例。

InstanceContextMode定义如下:


 // 摘要:
    //     指定可用来处理包含在传入消息中的调用的服务实例数。
    public enum InstanceContextMode
    {
        // 摘要:
        //     为每个会话创建一个新的 System.ServiceModel.InstanceContext 对象。
        PerSession = 0,
        //
        // 摘要:
        //     新的 System.ServiceModel.InstanceContext 对象在每次调用前创建,在调用后回收。如果信道未创建会话,则该值的行为就如同
        //     System.ServiceModel.InstanceContextMode.PerCall 一样。
        PerCall = 1,
        //
        // 摘要:
        //     只有一个 System.ServiceModel.InstanceContext 对象用于所有传入呼叫,并且在调用后不回收。如果服务对象不存在,则创建一个。
        Single = 2, } 

既然InstanceContextMode有三个枚举值,那就说明WCF服务端的实例有三种表现形式。那在平时的开发过程中,我们应遵循什么样的原则来采用哪种实例模式。?

首先看看在三种实例模式下,服务端实例具有怎样的表现。

服务实现:在服务的构造函数中,初始化计数器,进行服务调用时,将计数器进行累加输出。如下:


private int _counter;
public AddService()
{
    _counter = 0;
    Console.WriteLine("Single Mode");
} public int Add(int x, int y)
{
     Console.WriteLine("Start invoke...");
     Console.WriteLine("Invoke Thread Id is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);           
     _counter++;
     Console.WriteLine("counter is :{0}", _counter);
     return x + y;
}

1、各种实例模式的表现

PerCall模式

客户端调用时,服务端输出如下:

可以看出:PerCall 模式下,每次进行服务调用,实例都会进行初始化,并且实例销毁与服务调用是同一个线程完成的。

PerSession模式

客户端调用时,服务端输出如下:

可以看出:PerSession模式下,每次进行服务调用,实例都会进行初始化,但是对与每个代理,服务会使用同一个实例对象来为客户端服务。注意:同一客户端值的是同一个代理对象(透明代理),而不是计算机

使用会话模式有三个要求:1、使用支持会话的绑定 ;2、契约为会话契约;3、实例模式为:PerSession

Single模式

客户端调用时,服务端输出如下:

可以看出:Single模式下,所有客户端共享同一个服务实例对象。

2、如何选择服务实例模型

要选择服务实例模型,首先看看这三种模型各有什么优缺点:

PerCall:

优点:对于客户端调用来说,服务不用每次为服务的调用进行状态的同步,因为每次进行服务调用都会要求服务重新进行资源分配;能够对客户端的并发调用即使响应。只有在并发调用的时候,服务端才会在内存中创建和维护多个服务实例。在进行服务调用时,客户端仅仅持有服务的代理,而不会占用实际的资源,只有在发生服务调用时,才会获取资源。

缺点:对并行的调用需要自己进行线程同步;由于每次调用都需要重建资源的状态,对性能有一定的影响。

PerCall模式下,即使不停的创建于销毁服务实例,也不会释放与客户端的连接。因为建立连接远比服务实例的创建于销毁所需资源要多的多。

PerSession:

优点:服务端能识别不同的客户端代理,能为相同的客户端分配同一个实例,这个实例对象会一直保持,直到会话的结束。

缺点:整个会话期间,占用服务器资源,因此无法支持过多的客户端,因为创建服务实例代价比较大;与客户端、服务器模式一样存在可伸缩性的问题。

维持服务端与客户端的会话,WCF依靠传输层会话或者通过ws*绑定来模拟传输层会话。

Single:

优点:无需考虑线程的同步问题,客户端对服务的调用是排队进行的,服务一次只能为一个客户端进行处理,处理完成后才能进行为下一个客户端服务。

缺点:由于是串行的方式为客户端服务,所以效率比较低。服务的可伸缩性限制比较大

3、设计服务

3.1、PerCall模式

设计单调服务(PerCall模式时):虽然可以应用在任一服务上,但是在设计此类服务时还是应该注意到一些问题:由于客户端不用关心服务端实例模型,PerCall模式下,服务也是每次都为客户端端的调用分配新的实例对象,调用完成后就销毁实例,因此客户端需要进行一些状态管理。 为此,客户端在进行服务调用时,服务端实例对象实例化时需要从存储介质中获取状态,那么每个操作对都应该有只是一个参数,在进行服务调用时,通过参数来初始化状态。

示例:


     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    publicclass OrderService : IOrder,IDisposable
    {
        private int _counter;         public OrderService()
        {
            _counter = 0;
            Console.WriteLine("perCall Mode");
            Console.WriteLine("counter is {0}", _counter);
        }         #region IOrder Members         public void Order(string orderId)
        {                       
            int amount = GetStore(orderId);
            UpdateStore(amount - order.Number);
        }         #endregion         private int GetStore(string orderId)
        {
            string connectionString = ConfigurationManager.AppSettings["connectionString"];
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();
                 //获取库存数量信息
                return int;
            }
        }         private void UpdateStore(int p)
        {
            string connectionString = ConfigurationManager.AppSettings["connectionString"];
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();
                // 将库存信息更新到数据库                
            }
        }         public void Dispose()
        {
            //释放资源
        }
    }

3.2、PerSession模式

使用PreSession模式时,即使WCF在一个服务实现中,将服务实现的多个契约定义为会话或者非会话模式,但最好使用一致性配置,即所有契约都支持会话,避免将不同模式的服务定义在一个服务实现中。

3.3、Single模式

Single模式的服务于可伸缩性有着剧烈的冲突。Single模式的服务所有的客户端代理均使用同一个服务实例,WCF服务保证了服务状态的同步性。存在并发性访问比较高的情况下,它带来的是性能的严重下降。 只有在应用场景中适用单例的时候使用它。通常,应尽可能的使用其他方案来使状态同步,尽量避免使用Single模式.

后记:读《WCF 服务编程》后的对实例模式的重新认识。

WCF开发时如何选择正确的实例模式(InstanceMode)?的更多相关文章

  1. WCF服务类的实例模式(本文为转载)

    WCF开发时如何选择正确的实例模式(InstanceMode)?   在使用WCF实例模型时,你是否思考过这几个的问题: ”WCF中的实例模式如何正确应用”? ”使用WCF中的实例模式有何原则可以遵循 ...

  2. WCF揭秘(一)——简单的WCF开发实例

    一.WCF是什么 WCF是微软为了实现各个开发平台之间的无疑缝连接而开发一种崭新工具,它是为分布式处理而开发.WCF将DCOM.Remoting.Web Service.WSE.MSMQ.AJAX服务 ...

  3. [翻译] WCF运行时架构

    原文地址 http://www.cnblogs.com/idior/articles/971252.html 介绍 WCF具有非常易用的编程模型,服务开发者在掌握ABC的概念后可以很容易的使用WCF去 ...

  4. JavaScript是如何工作: 深入探索WebSocket和HTTP/2与SSE + 如何选择正确的路径!

    原文:<JavaScript是如何工作: 深入探索 websocket 和HTTP/2与SSE +如何选择正确的路径! 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 文章底部分 ...

  5. (转)权威支持: 选择正确的 WebSphere 诊断工具

    权威支持: 选择正确的 WebSphere 诊断工具 原文:https://www.ibm.com/developerworks/cn/websphere/techjournal/0807_supau ...

  6. 第十四章 Odoo 12开发之部署和维护生产实例

    本文中将学习将 Odoo 服务器作为生产环境的基本准备.安装和维护服务器是一个复杂的话题,应该由专业人员完成.本文中所学习的不足以保证普通用户创建应对包含敏感数据和服务的健壮.安全环境. 本文旨在介绍 ...

  7. J2EE开发时的包命名规则

    http://www.blogjava.net/paulwong/archive/2012/04/15/374675.html 转一个J2EE开发时的包命名规则,养成良好的开发习惯 代码编写规范目的: ...

  8. 实现在GET请求下调用WCF服务时传递对象(复合类型)参数

    WCF实现RESETFUL架构很容易,说白了,就是使WCF能够响应HTTP请求并返回所需的资源,如果有人不知道如何实现WCF支持HTTP请求的,可参见我之前的文章<实现jquery.ajax及原 ...

  9. SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework

    3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...

随机推荐

  1. iOS 开发一年总结

    收获很多 1. 一个人包办从构思, 设计, 实现, 推广的全过程, 对自己的能力, 特别是能力范围有很大的提升. 以前在公司上班仅仅局限在实现的局域内, 现在在做自己的产品时, 在设计时的取舍, 对工 ...

  2. 【BZOJ2428】[HAOI2006]均分数据

    Description 已知N个正整数:A1.A2.…….An .今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小.均方差公式如下: ,其中σ为均方差,是各组数据和的平均值,xi为第 ...

  3. setTimeOut传参数(转)

    无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数.带参数则立马执行,没有延时效果.可通过下面方式实现.  <script  ...

  4. 苹果Mac操作系统下怎么显示隐藏文件

      对于新手而已民,苹果的MAC操作系统刚用时用得很不习惯,比如想要显示被隐藏的文件时,不像windows有个“文件夹选项”对话框可以来设置,百度出来的结果都是用命令来操作,但我建议不要用命令去操作, ...

  5. hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=4715 [code]: #include <iostream> #include <cstdio ...

  6. MySQL的基本命令

    MySQL的基本命令 启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库 ...

  7. WEB开发人员必知的20+HTML5技巧(转)

    互联网科技发展的速度真可谓惊人的快,一个稍不留神,你就可能无法跟上它的步伐. HTML5的变化和更新也压倒不少人,这篇文章将向大家介绍一些最基本也非常必要的 HTML技巧. 1. 新的文档类型(Doc ...

  8. TCP协议可靠性数据传输实现原理分析

    http://blog.csdn.net/chexlong/article/details/6123087 TCP 协议是一种面向连接的,为不同主机进程间提供可靠数据传输的协议.TCP 协议假定其所使 ...

  9. ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置

    原文地址: ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.c ...

  10. Apache Tomcat下载、安装、配置图文教程

    本文已迁移到我的个人网站 http://www.wshunli.com 文章地址: http://www.wshunli.com/2016/03/19/Tomcat安装配置/ (整理截图.安装过程更加 ...