一、前言
最近忙于公司的在线升级项目,一个人要负责公司四大产品的在线升级,这四个产品是在Revit中以插件形式存在的,目前基于WCF来实现。等客户总量突破5万了,再重新用socket实现。
由于有服务器并发操作,所以要好好研究WCF的InstanceContext与ConCurrencyMode,找了好多文章,都没这篇写的言简意赅,特转发保留。
二、原文内容
原作者版权信息****************************************************************************************************************
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://arthurshayne.blog.51cto.com/3491820/1241514
***************************************************************************************************************************
今天学习了徐长龙老师的<<跟我一起从零开始学WCF>>的第9讲<<会话,实例与并发>>,对实例与并发有点混于是去网上查了一下,发现一篇不错的文章推荐给大家http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and#Instance。
由此谈一些自己对实例与并发的看法,实例与并发不是同一件事情,但又相互有影响。以下我就举一些有趣的例子来谈谈我对WCF中实例与并发的理解。
先 照本宣科一下,WCF的实例通过InstanceContext属性来指定,可以的取值是 Single, PerSession, PerCall。并发通过ConcurrencyMode属性来指定,可以的取值是 Single, Multiple, Reentrant。它们的组合就有3*3=9种。Reentrant的并发模式实质上就是Single的一个特殊情况最后再讨论。 InstanceContext 用于控制服务对象的个数,ConcurrencyMode用于控制服务对象是否可以同时服务多个请求。
好了我们开始举例,假如我们的服务是做早点,InstanceContext决定了我们有几个师傅来做早点,而ConcurrencyMode决定了每个师傅只能一个一个的做还是同时把要做的一起做。下面开始分情况逐一说明:
1. InstanceContext = Single & ConcurrencyMode = Single
InstanceContext = Single 我们这个早点铺就一个师傅
ConcurrencyMode = Single 师傅一次只能做一件事儿
不难想象如果买早点的人多了就会排着长长的队,而且如果前面有一个人要5套早点,那后面的人只能等那个人完事儿才能轮到自己。对师傅能力要求不高,一次做好一件事儿就好。
2.InstanceContext = Single & ConcurrencyMode = Multiple
InstanceContext = Single 我们这个早点铺就一个师傅
ConcurrencyMode = Multiple 师傅同时做所要做的事儿
这个是早点铺老板想要的情况,雇最少的人干最多的事,但是对做早点的师傅要求非常高,一次要做好很多事。不能人一多就做乱了把张三的烧饼少做一个,把李四的豆浆多做了一碗等。
3.InstanceContext = PerSession & ConcurrencyMode = Single
InstanceContext = PerSession 为每个顾客提供一个师傅专门服务(顾客来时现招,顾客走后就解雇)
ConcurrencyMode = Single 某一时刻只有一个师傅工作,每个师傅一次只能做一件事儿。
这 在现实生活中不可能存在但在计算机中却非常常见,所以我的例子只是说明关键问题,请不要太较真。这时第个顾客都会有一个专门的师傅来服务,但我们只有一个 厨房并且只能容下一个师傅,给张三服务的师傅做早点时别的师傅只能等待。师傅一次只能做一样东西,如果一个顾客要了很多的东西,那师傅一样一样的来做。所 以可以还是单线程只是有多个师傅而已。对师傅能力要求不高,一次做好一件事儿就好。
4.InstanceContext = PerSession & ConcurrencyMode = Multiple
InstanceContext = PerSession 为每个顾客提供一个师傅专门服务(顾客来时现招,顾客走后就解雇)
ConcurrencyMode = Multiple 所有的师傅同时工作,每个师傅可以同时做所要做的所有事儿
这在现实生活中也是不可能存在的。这时每个顾客都会有一个专门的师傅来服务,并且师傅们都可以同时工作,并且师傅可以同时做所有要做的所有早点。对师傅的要求较高,因为只是同时处理一个顾客的所有早点。
5. InstanceContext = PerCall & ConcurrencyMode = Single
InstanceContext = PerCall 为每个顾客要的每个需求都提供一个师傅专门服务(顾客提出要求时现招,师傅做完后就被解雇)
ConcurrencyMode = Single 某一时刻只有一个师傅工作,每个师傅只用做一件事儿。
这在现实生活中也是不可能存在的。这下师傅更多了,与情况3一样在某一时刻只能有一个师傅工作,不同的是师傅只用做一件事儿。对师傅能力要求不高,能做好一件事儿就好。
6. InstanceContext = PerCall & ConcurrencyMode = Multiple
InstanceContext = PerCall 为每个顾客要的每个需求都提供一个师傅专门服务(顾客提出要求时现招,师傅做完后就被解雇)
ConcurrencyMode = Multiple 所有的师傅同时工作,每个师傅只用做一件事儿。
这在现实生活中也是不可能存在的。这时客户的满意度理论上是最高的,顾客的每个要求都有师傅在做,而且所有的师傅在同时做事儿。当然这对早点铺的老板要付出的代价是最大的。对师傅能力要求不高,能做好一件事儿就好。
7. InstanceContext = * & ConcurrencyMode = Reentrant
这 种情况比较特殊,假如我们不生产早点全是从别的早点铺去买来然后再倒手给顾客,传说中的骑驴。这时假如顾客说出需要什么需要5秒钟的时间,我们打电话向其 它店索要,其它店再把东西送到需要1分钟,再把送来的东西给到顾客手中需要5s的时间。可见店内处理时间为10s,大量的时间在调货的时间(调用别的服 务)。所以这时比较合理的处理是,利用调货的时间来处理后面顾客的需求,在这1分钟的时间里可以处理20个顾客的需求,并且20个调货请求也已经发送。等 到第1个顾客的货送到后再转回来为其完成剩下的服务,这样可以节省很多后面顾客等待的时间。InstanceContext无论取什么值都与 ConcurrencyMode = Single的差不多只是针对有外部调用的情况有所优化。
我在上面提到的对师傅要求高或较高的情况, 也就表明我们的程序需要做一些线程安全的处理,保证我们的程序在多线程的情况下不会出现错误。对师傅要求不高的情况就是不存在并发的情况。以上是我对 InstanceContext和ConcurrencyMode的一点个人理解,如有不妥之处请指教。
原文版权信息**************************************************************************
本文出自 “唯有文字划破时空” 博客,请务必保留此出处http://arthurshayne.blog.51cto.com/3491820/1241514