`

《WCF按部就班学习系列8_WCF并发管理概述》(上)

阅读更多

《WCF按部就班学习系列8_WCF并发管理概述》,本文的主要结构为:1)WCF并发管理的概述2)WCF服务并发模式、WCF实例模型和并发模型关系、限流概述3)实现代码分析及运行结果4)源码下载5)下一篇计划6)参考说明
(1)WCF并发管理的概述(what)
1.当多个线程同时访问相同的资源的时候就会产生并发,WCF缺省情况下会保护并发访问。
2.对并发访问需要恰当处理,控制不好不仅会大大降低WCF服务的吞吐量和性能,而且还有可能会导致WCF服务的死锁。
3.如果需要的话,并发管理能够确保服务(或者服务访问的资源)执行在特定的线程上。
4..ServiceBehavior特性的ConcurrencyMode属性负责管理服务实例的并发访问:
ConcurrencyMode属性是个枚举类型,有三个值:ConcurrencyMode.Single、ConcurrencyMode.Reentrant和ConcurrencyMode.Multiple

ConcurrencyMode枚举值负责控制并发调用是否允许以及何时应用到服务实例上。
5.WCF提供了两种同步模式。自动同步(Automatic Synchronization)要求WCF同步访问服务实例。它的实现非常简单,易于使用,但只能用于服务与回调类。
手动同步( Manual Synchronization)增加了开发者实现同步的负担,要求实现特定的应用程序集成。开发者必须使用.NET同步锁,这也是目前实现同步的一条专门的原则。
手动同步的优势在于它可以用于服务和类似于服务的非服务类,允许开发者优化吞吐量与可伸缩性。

(2)WCF服务并发模式、WCF实例模型和并发模型关系、限流概述
2.1WCF服务并发模式
【1】ConcurrencyMode.Single
如果服务被设置为ConcurrencyMode.Single.WCF会为服务实例提供自动同步,并通过关联服务实例与同步锁以禁止并发调用。
单线程处理模式,同一个服务实例不会同时处理多个请求。当服务在处理请求时会对当前服务加锁,如果再有其它请求需要该服务处理的时候,需要排队等候。当服务处理完请求后会自动解锁,队列中的下个请求获取服务资源,继续处理。
例如:我们去银行去办理业务,如果营业厅中只有一个窗口对外服务的话,那当前窗口每次只能处理一个用户请求,如果再有其它用户需要办理业务的话,只能排队等待。直到我办理完业务后,营业窗口才能为队列中下个用户提供服务。
【2】ConcurrencyMode.Reentrant
可重入的单线程处理模式,它仍然是单线程处理。服务端一次仍然只能处理一个请求,如果有多个请求同时到达仍然需要排队。与单线程不同的是,请求在处理过程中可以去调用其它服务,等到其它服务处理完成后,再回到原服务等待队列尾排队。在调用其它服务的过程中,会暂时释放锁,其它等待线程会趁机进行服务的调用。这种模式常见于服务端回调客户端的场境中。
例如:我们去银行办理业务,营业厅中还是只有一个窗口对外服务,一次只能处理一个用户请求。我向银行服务员请求办理开户业务,从此刻开始该服务被我锁定,其它人员只能排队等待。

在服务员办理业务的过程中,会让我填写开户申请表,这个签字的过程就是服务端对客户端的回调过程。由于填写开户申请表的时间会很长,为了不耽搁后面排队顾客的时间,我暂时释放对服务员的锁定,到旁边填写申请表,让后面的人员办理业务。在我签完字后再回到队列中等待服务,当再轮到我的时候我再次锁定服务,把凭据交给服务员,让他继续处理我的业务,这相当于服务的“重入”过程。 等到业务办完后,我会离开银行柜台,释放对该服务的锁定,等待队列中的下个人员又开始锁定服务办理业务了。
【3】ConcurrencyMode.Multiple
多线程模式,多线程模式可以很好地增加系统的吞吐量。当多个用户请求服务实例时,服务并不会加锁,而是同时为多个请求服务。这样一来对所有用户共享的资源就会产生影响,所以这种多线程的访问模式需要对共享资源做好保护,大部份的情况下需我们的手动编写代码来实现多线程之间的访问保护。
例如:我们去吃烤肉串,烤肉串的师傅可以同时为多个顾客烤制,而不用一个一个地排队等待,这就是典型的多线程处理模式。但这种模式如果不对肉串很好保护得的话那可麻烦了,比仿,我要的是3串麻辣味的,你要的是3串香辣味的,他要的是3串原味的,烤肉的时傅在烤制的时候需要对这三份肉串做好保护,防止做出一些“五味俱全”的肉串来。
2.2WCF实例模型和并发模型关系
实例模型与并发模型的关系很密切,对于不同的实例模型,并发所需要的并发管理也不一样。
【1】ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.PerCall) --Single并发与PerCall实例模型
1.图8-1单调模式和单线程描述

2.对于PerCall的实例模型,每个客户端请求都会与服务端的一个独立的服务实例进行交互,就不会出现多个客户端请求争用一个服务实例的情况,也就不会出现并发冲突。也就是说这时候

ConcurrencyMode = ConcurrencyMode.Single写与不写都没关系,不会影响吞吐量的问题。
3.Single并发是系统默认的,而PerCall实例模型也是系统默认的。也就是说在默认情况下,WCF服务不会出现并发访问冲突的情况,当然对于静态数据或全局缓存数据会产生并发冲突,后面

会谈到如何解决这个问题。当然在进行回调操作的时候,有可能会出现等待超时的问题.
4.图8-2单调模型和单线程运行结果

5.从图8-2中我们看到实例变量的值都是1,静态变量的值是出现递增的情形,但由于没有采取同步策略,有可能会出现“线程9”和“线程11”这样的并发冲突的情况。

【2】ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.PerSession) --Single并发与PerSession实例模型
1.图8-3会话模型和单线程描述

2.对于PerSession实例模型,每个客户端对应一个服务实例,这样在不同客户端之间不会出现服务实例并发调用的情况,但每个客户端可以采用多线程调用同一个服务实例。
3.由于我们采用了ConcurrencyMode.PerSession并发模式,这使得多线程在调用同一服务实例的时候会进行线程排队,服务每次只对一个线程进行处理。
Single并发模式对多线程的客户端的吞吐量会带来影响,而对多个单线程的客户端访问并不起作用。
4.由于使用的PerSession实例模式,所以每个客户端共享同一个服务实例,当同一客户端使用多线程来访问服务的话,会访问同一个InstanceVariable变量。由于是Single并发模式,所以不

会对InstanceVariable变量产生并发冲突。
5.图8-4会话模型和单线程运行结果

6.从图8-4中可以看出,静态变量依然是被不同客户端不同的线程所共享;实例变量在同一个客户端的多个线程中是共享的,在不同客户端是各自独立的。
7.在Single并发+PerSession实例中,实例变量不会产生并发冲突,而静态变量可能会在不同的客户端之间产生并发冲突,在同一客户端多线程间不会产生并发冲突。
【3】ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,InstanceContextMode = InstanceContextMode.Single) --Single并发与Single实例模型
1.图8-5单例模型和单线程描述

2.对于Single实例模型,多个客户端对应一个服务实例,这样就容易发生多个客户端同时请求一个服务进行处理,产生并发问题。当采取Single并发模式时,多个客户端的并发访问问题会得

到解决,因为Single并发模式会使多个客户端请求进行排队,依次处理每个客户端的请求。
3.Single并发模式在Single实例模型中,每次只能处理一个调用请求,会对系统的吞吐量带来很大的影响。
4.图8-6单例模型和单线程运行结果

5.由于我们把实例模型设为Single,那所有客户端所有线程调用同一服务实例,故这些线程共享InstanceVariable实例变量,由于并发模式是Single模式,所以不会对此变量产生并发冲突。

而对于StaticVariable静态变量,而言也是所有客户端线程所共享的,但这里的静态变量StaticVariable不会产生并发冲突,因为只有一个服务实例来操作此静态变量。
【4】ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerCall) --Reentrant并发与PerCall实例模型
1.图8-7单调模型和单线程可重入模型描述

2.要解决这个问题,我们可以采用Reentrant并发模式,Reentrant模式依然是单线程模式,只是它允许客户端加调用能再回到服务端继续执行。
3.图8-8单调模型和单线程可重入模型运行结果

4.客户端:多线程发起调用时间是一样的,即向服务端发出的请求几乎是同一时间的。而线程结束的时间差别很大,之间几乎相差5秒。
服务端:确实有三个服务实例响应客户端的三个线程。但从其发起调用和调用结束的时间来看,这三个服务实例并非同时发起对客户端的回调,而是有严格的先后次序。
5.调用模型有三种:“请求-响应”(默认)、“One-Way”和“Duplex”。
这里我们没有明确指出采用哪种调用模式,因此为默认使用“请求-响应”方式。而“请求-响应”模式,客户端必须等服务端“响应”完成上一次“请求”后才能发出下一步“请求”。因此

虽然客户端使用多线程方式来调用服务,但最后的执行结果仍然表现出顺序处理。
6.要想使服务端能够并行处理客户端请求的话,那我们就不能使用“请求-响应”的调用模式,我们可以使用One-Way的方式来调用服务。
因此我们可以把服务端的ServiceMethod方法契约修正如下:
[OperationContract(IsOneWay=true)]
void ServiceMethod();
7.图8-9单调模型和单线程可重入模型(One-Way)运行结果

8.从图8-9中的结果我们看出
客户端:多线程的发起调用的时间是一样的,结束调用的时间也是一样的,并且发起调用和结束调用之间并没有时间延迟,这说明客户端多线程各自独立地向服务端发出调用成功。
服务端:确实在服务端产生三个实例处理客户端调用,并且这三个服务实例回调客户端的时间是相同的,但客户端回调结束的时间相差太大有明显的5秒延迟。
9.由于回调契约中的方法契约ClientMethod没有明确设置调用方式,所以也是默认“请求-响应”的调用方式,如果回调没有完成,则下个回调只能处于阻塞状态。因此导致服务端的回调虽然

同时发起,但结束回调的时间却差别很大。
下面我们在上面的基础上再试着把回调契约中的ClientMethod方法契约声明为One-Way
[OperationContract(IsOneWay=true)]
void ClientMethod();
10.图8-10单调模型和单线程可重入模型(One-Way(client))运行结果

11.从图8-10中我们可以看到
客户端:多线程异步调用
服务端:多线程异步调用,中间再没有发生延迟情况。
话又说回来,这种回调契约IsOneWay=true调用的方式却并不是ConcurrencyMode = ConcurrencyMode.Reentrant的并发模式。
12.上面的例子,我们是用一个代理的多个线程调用WCF服务,下面我们把客户端代码修改一下,实现多个代理用各自的线程调用WCF服务。为了能明确表达Reentrant并发模式,我们服务端方

法契约的IsOneWay=true去掉。
13.图8-11单调模型和单线程可重入模型(One-Way(C)和请求-响应(S))运行结果

14.从图8-11中可以看出,
在客户端三个服务被同时发出,调用结束后几乎同时返回。在服务端,也几乎同时向客户端发出回调,客户端在经过5秒的延迟后也几乎同时返回。休现了实例之间的无关。
15.所以在研究并发的时候不应当只研究“并发模型”和“实例模型”,还应当考虑到“调用模型”。
【5】ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession) --Reentrant并发与PerSession实例模型
1.图8-12会话模型和单线程可重入模型描述

2.而Reentrant并发模式,依然是个单线程的模式,即某时刻只能有一个线程调用服务实例,其余的线程处于等待队列中。但是当某线程回调客户端操作时,该线程就不再锁定该服务实例,等

待队列中的下个线程将锁定服务实例进行调用。当回调客户端的线程执行完客户端调用后再回到服务端时,它将进入线程等待队列中重新排队等待。
3.在“Reentrant并发+PerSession实例”模式中关于“调用方式(请求-响应、OneWay和Duplex)”对运行结果的影响,与上面“Reentrant并发+PerCall实例”模式中的“调用方式”对结果

的影响是一样的。
4.下面我们依然把服务契约中的方法契约调用设置为IsOneWay=true。
5.图8-13会话模型和单线程可重入模型(IsOneWay)运行结果

6.从图8-13中我们看到
客户端中我们使用同一个代理对象的多线程技术向服务端发送请求,在这里我启用了两个客户端。
而服务器端一共产生了两个实例,每个实例代表一个客户端的调用。在每个服务对象中,我们可以看到三个客户端回调的时间基本相同,而客户端回调返回的时间却相隔5秒钟。
【6】ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.Single) --Reentrant并发与Single实例模型
1.图8-14单例模型和单线程可重入模型描述

2.对于“Single实例模型+Reentrant并发模式”与“PerSession实例模型+Reentrant并发模式”有些相似,是单线程重入处理模式。如果调用方式是“请求响应”方式时,如果是同一个代理

的多个线程会受到阻塞,如果是多个代理则不同代理会并行调用;如果是OneWay调用模式,则不会出现任阻塞情况.
3.上面“Single实例模型+Reentrant并发模式”与“PerSession实例模型+Reentrant并发模式”这两个模型就与“去银行排队”的例子很相似。
4.图8-15单例模型和单线程可重入模型描述运行结果

5.从图8-15中我们看出两个客户端的六个线程的确调用服务端的同一个实例,用蓝色和绿色标出来的执行结果分别是不同客户端的线程回调情况。我们可以看出两个客户端之间是并行运行的

,而同一个客户端的三个线程则是排队调用的--因为用的是“请求-响应”的调用模式。
6.到目前为至我们研究完了PerCall和Reentrant两种并发模式,这两种并发模式都是单线程调用,每个调用都会独占其服务,因此并不会对服务实例产生并发调用的冲突。

(待续)

分享到:
评论

相关推荐

    《WCF按部就班学习系列8_WCF并发管理概述》

    **限流概述**是WCF并发管理中的另一个重要概念。限流是控制服务处理速率的一种机制,可以防止过多的并发请求导致系统资源耗尽。WCF通过设置服务的行为配置,可以限制并发请求数、最大接收消息数等,以达到服务级别的...

    《WCF按部就班学习系列7_WCF事务概述》

    让我们深入探讨一下“WCF按部就班学习系列7:WCF事务概述”中的核心知识点。 1. **WCF事务属性**:在WCF服务中,可以通过配置或编程方式启用事务。服务行为`ServiceBehavior`可以设置`TransactionEnabled`属性为`...

    《WCF按部就班学习系列1_WCF基础知识概述》

    在“WCF按部就班学习系列1”中,我们将深入探讨WCF的基础知识,包括服务契约、宿主定义等关键概念。 **服务契约** 服务契约是WCF中的核心概念,它定义了服务提供的操作及其交互方式。服务契约通过接口(Interface...

    《WCF按部就班学习系列4_WCF实例管理概述》

    WCF实例管理的概述,WCF服务实例激活类型三种方式概述和单例服务的完整代码。

    《WCF按部就班学习系列6_WCF错误概述》

    **WCF错误概述** Windows Communication Foundation (WCF) 是微软提供的一个全面的、统一的编程模型,用于构建面向服务的应用程序。在WCF中,错误处理是不可或缺的一部分,确保服务的稳定性和可靠性。本篇文章将...

    《WCF按部就班学习系列3_WCF数据契约概述》

    学习这个系列,初学者可以理解WCF的基本架构,掌握如何定义和使用数据契约,创建服务契约,以及如何在不同的环境中(如IIS、自承载等)部署和运行WCF服务。同时,通过实际的代码示例,有助于深入理解和应用WCF技术。

    《WCF按部就班学习系列2_WCF服务契约概述》

    在本文中,我们将深入探讨WCF(Windows Communication Foundation)服务契约这一核心概念,以及如何通过实例来理解并实现它的重载。WCF是.NET Framework中一个强大的服务导向架构,用于构建分布式应用程序,允许不同...

    《WCF按部就班学习系列5_WCF操作概述》

    **WCF(Windows Communication Foundation)**是微软推出的一种面向服务的通信框架,它提供了一种构建高度互操作的、安全的、可靠的服务的方法。在WCF中,**操作**是服务的基本工作单元,用户通过调用这些操作来与...

    WCF_AsyncCall.rar_WCF_AsyncCall_wcf_wcf winform_并发_线程池

    C#WCF 服务并发管理,编程源代码,包括线程池的例子。

    WCF服务编程中文版_1

    当前pdf总共有7个部分: WCF服务编程中文版_1 WCF服务编程中文版_2 WCF服务编程中文版_3 WCF服务编程中文版_4 WCF服务编程中文版_5 WCF服务编程part1 WCF服务编程part2

    WCF_idesign_1 WCF_idesign_1 WCF_idesign_1

    8. **调试与诊断**:学习如何通过WCF的诊断工具和日志功能来排查问题。 9. **服务宿主**:WCF服务可以宿主在IIS、自承载或Windows服务中,理解不同宿主的优缺点和适用情况。 10. **服务版本管理**:如何设计服务...

    WCF服务编程中文版_3

    当前pdf总共有7个部分: WCF服务编程中文版_1 WCF服务编程中文版_2 WCF服务编程中文版_3 WCF服务编程中文版_4 WCF服务编程中文版_5 WCF服务编程part1 WCF服务编程part2

    wcf.rar_wcf_wcf C#

    标题中的“wcf.rar_wcf_wcf C#”暗示了这是一个关于Windows Communication Foundation(WCF)的项目,其中包含了C#语言的实现。WCF是微软.NET Framework的一部分,用于构建可互操作的分布式系统,允许服务提供者和...

    WCF服务编程中文版_5

    当前pdf总共有7个部分: WCF服务编程中文版_1 WCF服务编程中文版_2 WCF服务编程中文版_3 WCF服务编程中文版_4 WCF服务编程中文版_5 WCF服务编程part1 WCF服务编程part2

    WCF服务编程中文版_2

    当前pdf总共有7个部分: WCF服务编程中文版_1 WCF服务编程中文版_2 WCF服务编程中文版_3 WCF服务编程中文版_4 WCF服务编程中文版_5 WCF服务编程part1 WCF服务编程part2

    WCF.rar_ChannelFactory_WCF DynamicProxy_WCF 动态_wcf 动态调用_动态WCF

    **WCF(Windows Communication Foundation)** 是微软推出的一种面向服务的、用于构建分布式应用程序的框架。它提供了多种机制,如消息交换、服务发现、安全性和事务处理,来帮助开发者构建可伸缩、可靠且安全的网络...

    WCF教程(Pro_WCF_Practical_Microsoft_SOA_Implementation-3297)

    本教程“Pro_WCF_Practical_Microsoft_SOA_Implementation-3297”专注于实践性学习,帮助开发者深入理解WCF的核心概念和技术,以及如何在实际项目中有效应用。通过一系列示例,你将学习到如何创建、配置和服务的调试...

    WCF大文件断点下载.rar_wcf_wcf文件上传_worthsdn_下载_远程下载

    在.NET平台上,Windows Communication Foundation(WCF)是一个强大的服务架构,用于构建分布式应用程序。本教程主要探讨了如何利用WCF实现大文件的断点下载功能,这是一个在远程文件传输中非常实用的技术。WCF文件...

    WCF.rar_wcf_whalewpf

    在“WCF.rar_wcf_whalewpf”压缩包中,包含的文件主要涉及WCF服务的创建、调用以及不同宿主方式的实现。** 1. **WCFClient**: 这个文件夹很可能包含了WCF服务的客户端应用程序,用于调用WCF服务。在WCF中,客户端...

    WCF_Test.rar_tastevk1_wcf_wcf双工

    标题中的"WCF_Test.rar_tastevk1_wcf_wcf双工"暗示了这是一个关于Windows Communication Foundation(WCF)的示例项目,特别关注的是双工通信模式。WCF是微软提供的一种.NET框架,用于构建分布式应用程序,它允许...

Global site tag (gtag.js) - Google Analytics