让两个不同的 WCF 客户端(即代理)引用 WCF 服务的同一实例的唯一方法是使用InstanceContextMode=InstanceContextMode.Single
。如果缩放是一个问题,那么这是一个糟糕的选择,所以你想使用PerCall
如果可以的话。
当你使用PerCall
, each CALL向WCF服务获取自己的WCF服务实例。不共享服务实例,但这并不意味着它们不共享相同的后端存储(例如数据库、内存、文件等)。只要记住,PerCall
允许每个call同时访问您的 WCF 服务。
The ConcurrencyMode http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.concurrencymode.aspx设置控制服务本身的线程模型。设置为Single
限制所有 WCF 服务实例在同一线程上运行。因此,如果您有多个客户端同时连接,它们在 WCF 服务端一次只会执行一个。在这种情况下,您可以利用 WCF 来提供同步。正如您所看到的,它会正常工作,但请将此视为仅对同步进行宏观级别的控制 - 每个 WCF 服务调用将在下一个调用执行之前完整执行。
Setting ConcurrencyMode
to Multiple
但是,将允许所有 WCF 服务实例同时执行。在这种情况下,您负责提供必要的同步。将此视为对同步进行微观级别的控制,因为您只能同步每个调用中需要同步的部分。
我希望我已经解释得足够好,但这里是 MSDN 文档的片段ConcurrencyMode http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.concurrencymode.aspx万一:
将 ConcurrencyMode 设置为 Single 指示系统限制
一个线程的服务实例
一次执行,这释放了
让你免于处理线程
问题。值为 Multiple 意味着
服务对象可以通过以下方式执行
任一时刻有多个线程。在
这种情况下,必须保证线程
安全。
EDIT
你问
那么,在使用 ConcurrencyMode.Single 时,使用 PerCall 与 Single 相比是否会提高性能?或者反之亦然?
这可能取决于服务。
With InstanceContextMode.PerCall
,通过代理为每个调用创建一个新的服务实例,因此您需要处理实例创建的开销。假设您的服务构造函数没有做太多事情,这不会成为问题。
With InstanceContextMode.Single
,在应用程序的生命周期中仅存在一个服务实例,因此实际上不存在与实例创建相关的开销。然而,这种模式只允许一个服务实例来处理将进行的每个调用。因此,如果同时进行多个调用,则每个调用都必须等待其他调用完成才能执行。
无论如何,我是这样做的。使用PerCall
实例上下文与Multiple
并发。在 WCF 服务类中,创建静态成员来为您管理后端数据存储,然后根据需要使用以下方法同步对这些静态成员的访问:lock
陈述,volatile
字段等。这使您的服务可以很好地扩展,同时仍然保持线程安全。