3

我有一个带有 ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,ConcurrencyMode = ConcurrencyMode.Multiple)的 WCF 服务。我想使用 ThreadStatic 变量来获取数据。

我开始担心是否有可能对相同或不同 operationContracts 的两个并行请求由同一个线程服务器端处理,因为如果发生这种情况,我的 ThreadStatic 变量将被覆盖。(即类似于 ASP.NET 中 HttpHandlers 和 HttpModules 之间的线程更改)

我用相同的 ServiceBehaviour 和 maxConcurrentCalls="2" 做了一个尖峰服务。之后,一个 wcf 客户端用 50 个并行请求调用了该服务,而我的担心并没有发生。然而,这并不是 100% 的证明。

预先感谢!

4

3 回答 3

4

无论 ConcurrencyMode 是什么,ThreadStatic当您的请求终止并且线程返回到线程池时,一个值将保持不变。同一线程可以重复用于后续请求,因此可以看到您的ThreadStatic值。

显然这对于​​两个并发请求是不正确的,因为根据定义,它们将在不同的线程上执行。

来自评论:

根据定义,MSDN 还说:'服务实例是多线程的。没有同步保证。因为其他线程可以随时更改您的服务对象,所以您必须始终处理同步和状态一致性。所以它不是那么明显:)

这意味着多个请求可以同时访问您的服务类的单个实例。因此,您需要处理对服务类实例成员的任何访问的同步。

但是ThreadStatic,根据定义,成员一次只能由一个线程(因此一个请求)使用,因此不需要同步。

于 2012-09-19T08:40:46.337 回答
1

您的问题的直接答案是乔的答案。

但是,您在评论中提到您正在使用环境设计模式。该模式已在 WCF 中作为 OperationContext 实现,并且专门设计为可扩展的。我强烈建议在任何自定义线程存储上使用 OperationContext

请参阅在哪里存储当前 WCF 调用的数据?ThreadStatic 安全吗?

于 2012-09-19T16:28:36.770 回答
0

我想在这里添加乔的答案,因为如果您需要存储状态,我建议您对请求使用某种相关性。线程模型在生产中会变得非常复杂和不可靠。

此外,现在假设您有两个托管此服务的 IIS 服务器和一个硬件或软件负载均衡器,以便您可以使用它。为了确保收集到正确的状态,您需要关联,因为您永远不知道服务将在哪个服务器上启动。在下面的帖子中,我模拟了一个简化版本的工作方式。要记住的一件事是,SessionState需要将其保存在服务的所有实例的共享位置,例如 AppFabric 缓存服务器。

两个 WCF 方法之间的全局变量

于 2012-09-19T11:47:30.787 回答