4

通过阅读本文,我认为客户端无法在 IsInitiating=true 服务方法执行之前运行 IsInitiating=false 服务方法。但是在我们的 WCF 服务中是一个单例,我可以随意调用服务方法,不需要先调用 IsInitiating=true 服务方法吗?这真的如何运作?

我正在使用 IAuthorizationPolicy Evaluate 我设置这样的临时上下文

evaluationContext.Properties["Principal"] = userContext;

这可能是问题吗?

我现在必须检查 messageAction 而不是使用 IsInitiating,如果它不是登录服务方法,则检查是否存在存储的上下文,否则会抛出安全异常。

编辑 :

这是服务设置使用的内容:

InstanceContextMode = InstanceContextMode.PerCall
oncurrencyMode = ConcurrencyMode.Multiple
SessionMode = SessionMode.Required
4

1 回答 1

1

IsInitiating并且IsTerminating用于与 一起使用InstanceContextMode.PerSession,当需要在连续调用中保留服务器上的每个会话状态时,它会划分界限,从而允许控制与每个会话关联的服务实例的生命周期。会话模式实例化的好处是状态可以保留在服务器上,而无需从数据库中重新水化状态,尽管这最终会限制可伸缩性,因为并发会话的数量是有限的(每个新会话创建并持有一个实例直到终止,这会消耗内存)。

如果单例是指具有InstanceContextMode.Single实例化的 WCF 服务,那么 WCF 会话(以及 IsInitiating / IsTerminating)将不适用,因为服务器上将为所有客户端的所有调用保留一个状态。InstanceContextMode.Single(假设为ConcurrencyMode = ConcurrencyMode.Multiple)应谨慎使用,因为线程安全将成为一个问题,例如单例可用于不可变缓存(例如静态数据服务)或无状态计算。

这篇 MSDN 文章在这里很好地解释了实例化模式、会话和并发之间的关系

编辑

为了让 WCF 会话在Initiating和之间保持状态Terminating calls,您需要将 更改InstanceContextModeInstanceContextMode.PerSession,因为这PerCall将在调用之间丢失所有状态(实例对象将在每次调用后有资格收集,而PerSession实例将保留到调用一种IsTerminating方法)。您还需要采用binding支持会话的方法。这里有一个基于 MSDN 计算器服务的示例。需要注意的另一件事InstanceContextMode.PerSession是,如果您在农场/云环境中横向扩展,则需要服务器关联(粘性会话)。

于 2015-03-11T10:52:33.600 回答