在WCF中,是否始终在与消息检查器相同的线程上调用操作?

时间:2012-12-04 18:31:14

标签: c# .net multithreading wcf

我有一个WCF线程问题我无法找到一个好的答案。我的IDispatchMessageInspector实现具有以下AfterReceiveRequest实现:

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
   return new SessionScope();
}

SessionScope的构造函数使用字典注册当前作用域,该字典基本上通过其线程跟踪它。然后我有以下操作:

[MyServiceBehavior]
public class Service1 : IService1
{
   public string GetData(int value)
   {
      // Uses SessionScope.Current object for various things
   }
}

GetData 保证是否会与先前检查过WCF消息的消息检查程序在同一个线程上运行?同样,BeforeSendReply也可以在同一个线程上运行吗?

2 个答案:

答案 0 :(得分:3)

假设您在IIS下运行,答案是否定的。

IIS有一个名为“线程敏捷”的东西,这意味着单个请求可以跳转线程。我们遇到了一些问题,在一种情况下,我们通过使用http上下文解决了这个问题。

查看此问题的答案:Will a request in IIS run on a single thread?

答案 1 :(得分:3)

您无法保证请求将保留在同一个线程中。 IIS可以(并且将会)在线程之间传递它。

要实现您的目标,您可以将对象加载到OperationContext.Current(如果启用了aspCompatibilityMode,则加载HttpContext.Current)。我已经通过向OperationContext.Extensions列表添加对象来完成它:

首先,您的班级必须实施IExtension

public sealed class SessionScope : IExtension<OperationContext> {
  // your class details here
}

然后,您需要将对象添加到OperationContext:

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
   SessionScope scope = new SessionScope();
   OperationContext.Current.Extensions.Add( scope );
}

之后无论线程切换如何,它都可供您随时使用。