从阅读this开始,我认为客户端在执行IsInitiating = true服务方法之前无法运行IsInitiating = false服务方法。但是在我们的WCF服务中,我可以根据需要调用服务方法,不需要先调用IsInitiating = true服务方法吗?这真的有用吗?
我正在使用IAuthorizationPolicy Evaluate,我设置了一个像这样的临时上下文
evaluationContext.Properties["Principal"] = userContext;
这可能是问题吗?
而不是使用IsInitiating我现在必须检查messageAction,如果它不是登录服务方法,那么检查是否有存储的上下文,否则抛出securityexception。
编辑:
这是服务设置使用的内容:
InstanceContextMode = InstanceContextMode.PerCall
oncurrencyMode = ConcurrencyMode.Multiple
SessionMode = SessionMode.Required
答案 0 :(得分:1)
IsInitiating
和IsTerminating
适用于InstanceContextMode.PerSession
,用于划分连接调用时是否需要保留服务器上的每个会话状态,从而允许服务实例的生命周期与每个要控制的会话相关联。会话模式实例化的好处是可以在服务器上保留状态,而不需要例如需要从数据库中重新水化状态,尽管这最终会限制可伸缩性,因为并发会话的数量是有限的(每个新会话创建并保存实例直到终止,这会消耗内存)。
如果通过singleton,您的意思是具有InstanceContextMode.Single
实例的WCF服务,那么WCF会话(和IsInitiating / IsTerminating)将不适用,因为在服务器上将保留单个状态以用于来自所有客户。 InstanceContextMode.Single
(假设为ConcurrencyMode = ConcurrencyMode.Multiple
)应谨慎使用,因为线程安全性是一个问题,例如singleton可用于不可变缓存(例如静态数据服务)或无状态计算。
This MSDN article here很好地解释了Instancing模式,Sessions和Concurrency之间的关系
修改强>
为了让WCF会话在Initiating
和Terminating calls
之间保持状态,您需要将InstanceContextMode
更改为InstanceContextMode.PerSession
,因为{{1}将失去调用之间的所有状态(实例对象在每次调用后都有资格进行收集,而使用PerCall
实例将被保留,直到调用PerSession
方法为止。您还需要采用支持会话的IsTerminating
。这里有一个基于MSDN计算器服务over here的示例。如果您在Farm / Cloud环境中扩展,则binding
需要注意的另一件事是需要服务器关联(粘性会话)。