我正在.NET 4中实现我的第一个REST服务,遇到了意想不到的事情。似乎我不理解微软ServiceModel的强调工作,但却找不到传统方式的答案。
要实现我的网络服务,我遵循了本教程中的步骤: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这不是正确的方法。
我的问题是:
谢谢。
答案 0 :(得分:2)
我建议的一件事是考虑使用WCF挂钩而不是Application_BeginRequest和Application_EndRequest方法。四个实例,这里有四个更有用的钩子:
AfterReceiveRequest - > BeforeCall - >方法调用 - > AfterCall - > BeforeSendReply
钩子非常强大。在调用方法之前检查参数(将一些日志记录集中到一个地方)并执行各种其他有用的操作。这些不是唯一可用的钩子,我也使用其他一些钩子。例如,GetInstance允许我覆盖服务类对象的创建(因此您可以使用依赖注入框架等)。
当我使用每次调用并发模式时,这些钩子加上方法调用本身在同一个线程上调用。希望这可以帮助。如果你愿意,我可以提供实现这些钩子的链接。
干杯
答案 1 :(得分:0)
您可能希望查看服务实现上的[ServiceBehavior]属性,因为它支持参数来控制创建的实例数以及使用的线程模型。
http://msdn.microsoft.com/en-us/library/cc681240.aspx
当你有
时[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyService : IMyService
您的服务将作为单例运行,但具有多个线程 - 最多为WCF配置中设置的阈值 - 调用您的方法。要强制它仅在一个线程上运行,从而序列化入站请求,请设置ConcurrencyMode.Single。
或者,您可以为每次通话启动新服务实例:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Single)]
public class MyService : IMyService
实例只有一个线程可以访问它。实际上,当你有InstanceContextMode.PerCall时,会忽略ConcurrencyMode,因为它始终是“Single”,并且每个实例都在自己的线程中运行。