我有一个带有ServiceBehavior的WCF服务(InstanceContextMode=InstanceContextMode.Single,ConcurrentMode=ConcurrentMode.Multle)。我想使用ThreadStatic变量来存储数据。
我开始担心是否有可能由同一个线程服务器端处理对相同或不同操作Contract的两个并行请求,因为如果发生这种情况,我的ThreadStatic变量将被覆盖。(例如,类似于ASP.NET中HttpHandlers和HttpModules之间的线程变化)
我使用相同的ServiceBehavior和maxConcurrentCalls="2"创建了一个尖峰服务。在那之后,一个wcf客户端用50个并行请求调用了该服务,我的担忧没有发生。然而,这并不是100%的证明。
提前感谢!
无论ConcurrencyMode如何,当您的请求终止并且线程返回到线程池时,ThreadStatic
值都将持续存在。同一个线程可以重复用于后续请求,因此可以看到您的ThreadStatic
值。
显然,对于两个并发请求,这是不正确的,因为根据定义,它们将在不同的线程上执行。
来自评论:
根据MSDN的定义,它还说:"服务实例是多线程的。没有同步保证。因为其他线程可以随时更改您的服务对象,所以您必须始终处理同步和状态一致性。"所以不那么明显:)
这意味着多个请求可以同时访问服务类的单个实例。因此,您需要处理对服务类实例成员的任何访问的同步。
然而,根据定义,ThreadStatic
成员一次只能由一个线程使用(因此只有一个请求),因此不需要同步。
你的问题的直接答案是Joe的答案。
然而,您在评论中提到您正在使用环境设计模式。该模式已经在WCF中作为OperationContext实现,并且专门设计为可扩展我强烈建议在任何自定义线程存储上使用OperationContext。
请参阅当前WCF调用的数据存储位置?ThreadStatic安全吗?
我想在这里添加到Joe的答案中,因为如果需要存储状态,我建议您对请求使用某种相关性。线程模型在生产中会变得非常复杂和不可靠。
此外,现在假设您有两个IIS服务器托管此服务,并有一个面向前的硬件或软件负载均衡器,以便您可以使用它。为了确保收集到正确的状态,您需要关联,因为您永远不知道该服务将在哪台服务器上启动。在下面的文章中,我模拟了一个简化版本的工作方式。需要记住的一点是,SessionState
需要保存在服务的所有实例的共享位置,例如AppFabric缓存服务器。
两种WCF方法之间的全局变量