这两天看artech的文章,有意外收获,而且收获还不小。WCF如果想简单点用,确实也比较简单,因为很多属性具有默认值。但往往在有些方面比较起Web
Service,有很多地方是不同的,就拿WCF支持并发来说吧。
要想了解WCF的并发,我们需要了解三种非常重要的东西:
1:实例上下文,即Instance
Context,它是对服务实例的封装,是实例服务管理过程中重要组成部分。
2:服务实例,即Service
Instance,真正的服务实例。
3:服务代理,即Service Proxy,客户端与真正服务沟通的桥梁。
服务实例与对应实例上下文的关系:
开发一个服务,我们首先需要确定它的服务实例,WCF共提供了三种不同的服务实例,而这三种服务实例对于它们的实例上下文又是有区别的。分别是:
1:单调服务,即请求/应答模式。无论是同一客户端还是不同客户端对服务的调用,都会统一创建全新的服务实例上下文。但对于单调实例来说,它返回的实例上下文为空,即无需维护实例上下文,实例上下文对单调服务来说是无实际意义的。为些当并发请求时,单调服务都能及时给与处理。
2:会话服务,针对同一客户端保持同一服务状态,不同的客户端不共享相同的实例上下文,这种模式介于单调服务以及单例服务之间,它和单例服务一样,也需要额外的去维护实例上下文。
3:单例服务,针对所有客户端始终只会创建一个服务实例上下文。这就意味着,每次客户端调用后都需要额外去维护实例上下文。
三种不同的实例模式下的关系图如下:
三种实例模式下对于并发的影响:
1:单调服务,由于在单调服务中,当一个请求到达服务端后都会全新的创建一个服务实例以及实例上下文,所以并不存在多个请求针对同一服务实例的并发调用情况,为此当有并发请求时也能及时得到响应。这也说明对于单调服务来说ConcurencyMode.Mutiple是没有意义的。
2:单例服务,由于服务实例的唯一性,所以每个请求到达服务端后都是调用同一服务实例,而且需要维护实例的上下文的一致性,也就是说当有多个请求并发调用时,会形成一个请求队列,进行串行执行,这大大影响了系统的并发性,不过我们可以通过设置WCF的并发模式来解决,及Concurrency
Mode,把此属性设置成ConcurencyMode.Mutiple,需要注意的是,这样做我们需要人为的控制多线程所带来的一系列问题。
3:会话服务的情况是前面两种的统一,这里就不再多说了。
问题:如果我们遵守上面的条例,是否服务真正的会启动并发模式呢?我看了artech的文章后,也下载了他的demo,有两个问题:
第一:确实没有真正的启动并发模式。那是因为没有设置UseSynchronizationContext。这个属性默认为true,即同步实例上下文,只要设置成false时,系统才会真正的启动并发模式,这点从他的demo程序中可以得到证明。
第二:也是artech的demo引起的问题,单例服务,如何实现并发,在artech的wcf剖析书中,提到单例服务要想实现并发,需要将Concurrency
Mode属性设置成ConcurencyMode.Mutiple,但我测试过,并不能真正启动并发,程序还是串行运行。只要设置UseSynchronizationContext为false后才行,但如果不同步上下文,那么设置成单例服务的意义就不存在了,这里我一时无法得到答案,请artech以及各位帮忙解答下其中原因,这里先谢谢了。