在《上篇》中,我通过一个具体的实例演示了WCF服务宿主的同步上下文对并发的影响,并简单地介绍了同步上下文是什么东东,以及同步上下文在多线程中的应用。那么,同步上下文在WCF并发体系的内部是如何影响服务操作的执行的呢?这实际上涉及到WCF的一个话题,即线程的亲和性(Thread Affinity),本篇文章将为你剖析WCF线程亲和机制的本质。

对于服务端来说,WCF消息监听和接收体系通过IO线程池并发的处理来自客户端的服务调用请求,所以并发抵达的服务调用请求消息能够得到及时的处理。但是,服务操作具体在那个线程线程执行,则是通过WCF的并发处理体系决定的。

在默认的情况下,WCF采用这样的机制控制并发操作的执行:如果在进行服务寄宿(IIS寄宿方式除外)的过程中,当前线程存在同步上下文,会将其保存在服务端分发运行时。等到需要执行服务操作的时候,WCF并发体系会判断分发运行时的同步上下文是否存在,如果不存在则在各个的线程中执行服务操作,否则,服务操作会被封送到该同步上下文中执行。

如果我们将某个服务寄宿于一个控制台(Console)应用之中,由于控制台程序的当前同步上下文为空,按照上面的并发操作执行机制,所有的请求操作会在各自的线程中并行地执行。所以,在流量允许的范围内,并发的请求能够得到及时地处理。

如果我们通过Windows Forms应用作为某个服务的宿主,服务操作的执行永远是以同步的方式执行的。也就是说,在某个时刻,仅仅只有针对某个服务调用的服务操作被执行,其他的调用请求都将被放入一个等待队列中。如果等待的时候超出了设定的超时时限(这在高并发的情况下会比较频繁),客户端会抛出TimeoutException异常。我们将服务操作与服务寄宿程序线程自动绑定的现象称为服务的线程亲和性(Thread Affinity)

在这种情况下,由于服务操作执行才UI线程中,可以正常得对Windows窗体上的控件进行操作。如果,你希望服务操作能够并发地被执行,就不得不打破这种线程亲和性,我们可以按照监控程序中的方式在服务类型上应用ServiceBehaviorAttribute特性将UseSynchronizationContext属性设置成False。但是在这种情况下,如果你需要对控件进行操作,你就需要调用Control类型的Invoke或者BeginInvoke方法,或者按照我们监控程序的方式借助于SynchronizationContext对象了。UseSynchronizationContext在ServiceBehaviorAttribute的定义如下面的代码所示,该属性的默认值为True。

   1: [AttributeUsage(AttributeTargets.Class)]
class ServiceBehaviorAttribute : Attribute, IServiceBehavior
   3: {
//其他成员    
bool UseSynchronizationContext { get; set; }
   6: }

相关文章:

  • 2021-11-08
  • 2021-10-07
  • 2021-08-28
  • 2021-05-19
  • 2022-12-23
  • 2021-08-11
  • 2021-06-18
  • 2022-03-02
猜你喜欢
  • 2021-06-25
  • 2022-12-23
  • 2021-11-22
  • 2021-09-22
  • 2022-12-23
  • 2022-01-07
  • 2021-11-15
相关资源
相似解决方案