Welcome

首页 / 软件开发 / WCF / WCF后续之旅(12) 线程关联性(Thread Affinity)对WCF并发访问的影响

WCF后续之旅(12) 线程关联性(Thread Affinity)对WCF并发访问的影响2011-01-03 cnblogs artech在本系列的上一篇文章中,我们重点讨论了线程关联性对service和callback的操作执行的影响:在service host的时候,可以设置当前线程的SynchronizationContext,那么在默认情况下,service操作的执行将在该SynchronizationContext下执行(也就将service操作包装成delegate传入SynchronizationContext的Send或者Post方法);同理,对于Duplex同行方式来讲,在client调用service之前,如果设置了当前线程的SynchronizationContext,callback操作也将自动在该SynchronizationContext下执行。

对于Windows Form Application来讲,由于UI Control的操作执行只能在control被创建的线程中被操作,所以一这样的方式实现了自己的SynchronizationContext(WindowsFormsSynchronizationContext):将所有的操作Marshal到UI线程中。正因为如此,当我们通过Windows Form Application进行WCF service的host的时候,将会对service的并发执行带来非常大的影响。

详细讲,由于WindowsFormsSynchronizationContext的Post或者Send方法,会将目标方法的执行传到UI主线程,所以可以说,所有的service操作都在同一个线程下执行,如果有多个client的请求同时抵达,他们并不能像我们希望的那样并发的执行,而只能逐个以串行的方式执行。

一、通过实例证明线程关联性对并发的影响

我们可以通过一个简单的例子证明:在默认的情况下,当我们通过Windows Form Application进行service host的时候,service的操作都是在同一个线程中执行的。我们照例创建如下的四层结构的WCF service应用:

1、Contract:IService

namespace Artech.ThreadAffinity2.Contracts
{
[ServiceContract]
public interface IService
{
[OperationContract]
void DoSomething();
}
}

2、Service:Service

namespace Artech.ThreadAffinity2.Services
{
public class Service:IService
{
public static ListBox DispalyPanel
{ get; set; }

public static SynchronizationContext SynchronizationContext
{ get; set; }

#region IService Members

public void DoSomething()
{
Thread.Sleep(5000);
int threadID = Thread.CurrentThread.ManagedThreadId;
DateTime endTime = DateTime.Now;
SynchronizationContext.Post(delegate
{
DispalyPanel.Items.Add(string.Format("Serice execution ended at {0}, Thread ID: {1}",
endTime, threadID));
}, null);
}

#endregion
}
}