.NET REST服务实现中使用线程池

Ale*_*lex 7 c# asp.net rest web-services

我正在.NET 4中实现我的第一个REST服务,并遇到了意想不到的事情.我似乎不理解Microsoft的ServiceModel的强调工作,但是找不到传统方式的答案.

为了实现我的Web服务,我遵循了本教程中的步骤:http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4. ASPX

服务有效.让我感到惊讶的是,Global.asax中的Application_BeginRequest和Application_EndRequest由不同的线程调用.查看堆栈跟踪,看起来这些线程基于某种线程池.

如果不做一些重构,这对我们来说是个问题,因为我们总是假设单个请求总是在同一个线程上运行,因此我们将一些变量保存在线程本地存储中.变量在Application_BeginRequest中初始化,并在Application_EndRequest中释放.看来,使用ServiceModel这不是正确的方法.

我的问题是:

  1. 在使用ServiceModel时,我可以假设哪些线程正在运行我的代码吗?
  2. 有没有办法将执行限制为单个线程?这有什么不好吗?
  3. 使用ServiceModel时,在请求期间存储变量的正确方法是什么?

谢谢.

Chr*_*ham 0

您可能需要查看服务实现上的 [ServiceBehavior] 属性,因为它支持控制创建多少实例以及使用哪种线程模型的参数。

http://msdn.microsoft.com/en-us/library/cc681240.aspx

当你有

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
                 ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyService : IMyService
Run Code Online (Sandbox Code Playgroud)

您的服务将作为单例运行,但具有多个线程(最多达到 WCF 配置中设置的阈值)调用您的方法。要强制它仅在一个线程上运行并从而序列化入站请求,请设置 ConcurrencyMode.Single。

或者,您可以为每个调用启动一个新的服务实例:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                 ConcurrencyMode = ConcurrencyMode.Single)] 
public class MyService : IMyService
Run Code Online (Sandbox Code Playgroud)

该实例将只有一个线程访问它。事实上,当您有 InstanceContextMode.PerCall 时,ConcurrencyMode 会被忽略,因为它始终是“Single”,并且每个实例都在自己的线程中运行。