65.9K
CodeProject 正在变化。 阅读更多。
Home

理解 WCF 并发模式和节流

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.63/5 (4投票s)

2013年4月2日

CPOL

5分钟阅读

viewsIcon

43165

在本小贴士中,我们将讨论 WCF 服务中可用的各种并发模式。

引言

在本小贴士中,我们将讨论 WCF 服务中可用的各种并发模式。我们将了解使用这些并发模式会产生什么影响,以及它们如何与 InstanceContextModes 协同工作。我们还将研究 WCF 节流,以及如何控制并发调用的数量和其他 WCF 配置参数。

背景 

我们已经了解了 WCF 服务如何提供各种实例模式(参考:理解 WCF 实例管理的初学者教程 [^])。实例模式只是与 WCF 服务相关的一个方面。每当客户端调用 WCF 服务函数时,该 WCF 服务类的实例都会在一个从线程池中获取的线程上创建。一旦实例被使用并且不再需要,线程将返回到线程池,以便可以回收用于进一步的请求。

WCF 并发模式使我们能够控制这些线程创建过程,从而使 WCF 服务创建者能够更好地、更理想地、或许更全面地控制 WCF 服务行为。

使用代码

现在让我们看一下各种可能的并发模式

  1. Single
  2. 多个
  3. 可重入

Single

Single 模式下,只有一个线程可以使用 WCF 服务类的实例。如果任何线程已经创建了该类的实例,那么后续的请求线程可以创建实例,但它们必须等待第一个线程完成使用其实例,然后才能有机会在其实例上执行操作。

这是默认模式,并且从并发角度来看,这种模式是最安全的,因为开发人员无需在代码中处理并发问题。

此模式可以这样可视化:在调用每个函数之前,线程获取一个锁,并在调用完成后释放该锁,以便其他线程可以继续执行。

由于此模式一次只允许一个线程处理实例,因此无论实例模式如何,此行为都将相同。即在 InstanceContextMode.SingleInstanceContextMode.PerSessionInstanceContextMode.PerCall 中,只允许单个线程访问 WCF 服务类的实例。

多个

Multiple 模式下,每个线程将拥有自己的 WCF 服务对象实例,并且它们将同时执行。现在这是最复杂的模式,因为所有并发问题都必须由服务处理。

现在让我们看看在各种 InstanceContext 模式下的行为

  • InstanceContextMode.Single:在此模式下,只有一个实例为所有客户端请求提供服务,并且由于 ConcurrencyMode 也设置为 Multiple,因此将为所有客户端创建多个线程。
  • InstanceContextMode.PerSession:在此模式下,将为每个客户端创建一个服务的单个实例,并且由于 ConcurrencyMode 设置为 Multiple,因此可以为每个客户端请求创建多个线程。
  • InstanceContextMode.PerCall:在此模式下,每次调用都会创建一个新实例,因此 ConcurrencyMode 设置为 Multiple 不会对行为产生太大影响,每次调用都将在单个线程中处理。

可重入

Reentrant 模式在某种程度上类似于 Single 模式,即每个线程都可以创建自己的实例,但要执行实例,它们必须等待任何其他线程完成使用该实例。此模式的主要区别在于,如果第一个线程的实例调用了其他服务或处理了客户端回调,那么将有机会执行第二个线程的实例。

现在,由于这类似于 Single 模式,并且一次只允许一个线程处理实例,因此无论实例模式如何,此行为都将相同。即在 InstanceContextMode.SingleInstanceContextMode.PerSessionInstanceContextMode.PerCall 中,只允许单个线程访问 WCF 服务类的实例,但只要实例调用了任何其他服务或进入处理客户端回调,其他线程将有机会执行其自己的 WCF 服务类实例。

注意:我们只从理论角度讨论了 ConcurrencyModes 。在大多数情况下,使用 ConcurrencyMode.Single。此外,在无状态场景中,默认实例模式为 PerCall,更改 ConsurrencyMode 将不会产生任何效果/影响,因此我们很少会想要更改并发模式的默认行为(即使更改了,也可能徒劳无功)。

关于节流的说明

设置 InstanceContextMode ConcurrencyMode 将处理服务行为。但是,我们应该或如何解决与访问服务的客户端数量、可以访问服务的线程数量或实例允许为该服务创建的会话数量相关的问题?

如果我们能够控制这些问题,那么我们就可以确信,即使服务因请求、会话和/或调用而被过度消耗,它也能保持一致的行为。

WCF 节流使我们能够指定和配置这些限制,以保护服务免受过度消耗。我们可以使用 ServiceThrottle 类通过代码(命令式)设置这些限制,或者在服务的 web.config 文件的 serviceBehavior 部分(声明式)设置这些限制。可以设置的主要属性是

  • MaxConcurrentSessions
  • MaxConcurrentInstances
  • MaxConcurrentCalls

关注点

这是关于 WCF 并发和节流理论方面的一个小贴士。我没有为这个小贴士提供任何示例代码,因为我自己从未有机会配置 ConcurrencyMode ,因为我主要处理无状态服务。但了解这些模式肯定很重要,因为我们应该了解这些内容,以便在可能需要它们的时候知道。

历史

  • 2013 年 4 月 2 日:初版。
© . All rights reserved.