使用WCF服务行为属性设置为ConcurrencyMode.Multiple和InstanceContextMode.PerCall时是否可能出现并发问题?我们有一个WCF服务,可以进行大量事务性NHibernate调用。有时我们会看到SQL超时,即使调用正在更新不同的行并且表设置为行级锁定。深入研究日志后,看起来不同的线程正在代码中输入相同的点(我们的事务使用块),并且更新在提交时挂起。然而,这没有意义,因为我们认为以下服务类属性强制执行每个服务调用的唯一线程:[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple,InstanceContextMode=InstanceContextMode.PerCall)]我们最近将并发模式更改为ConcurrencyMode.Single并且还没有遇到什么问题,但是这个bug很难重现(如果有人想刷这样的bug,请告诉我!)。不管怎样,这一切都让我想到了一个问题:PerCall的InstanceContextMode是否应该在服务中强制执行线程安全,即使ConcurrencyMode设置为多个?如何使用相同的服务实例为这两个调用提供服务?谢谢!让两个不同的WCF客户端(即代理)引用同一个WCF服务实例的唯一方法是使用InstanceContextMode=InstanceContextMode.Single。如果缩放是一个问题,这是一个糟糕的选择,所以如果可以的话,你想使用PerCall。使用PerCall,WCF服务的每个CALL都会获得它自己的WCF服务实例。没有共享服务实例,但这并不意味着它们不共享相同的后端存储(例如,数据库、内存、文件等)。请记住,PerCall允许每个调用同时访问您的WCF服务。ConcurrencyMode设置控制服务本身的线程模型。设置为Single会限制所有WCF服务实例在同一线程上运行。因此,如果您同时连接了多个客户端,它们将在WCF服务端一次只执行一个。在这种情况下,您可以利用WCF来提供同步。如您所见,它可以正常工作,但我认为这只是对同步的宏观级别控制——每个WCF服务调用都将在下一个执行之前完全执行。但是,将ConcurrencyMode设置为Multiple将允许所有WCF服务实例并发执行。在这种情况下,您负责提供必要的同步。可以将其视为对同步进行微观级别的控制,因为您只能同步每个调用中需要同步的那些部分。我希望我已经很好地解释了这一点,但这里有一个来自MSDN文档的ConcurrencyMode的片段,以防万一:将ConcurrencyMode设置为Single指示系统将服务实例限制为一次执行一个线程,这使您不必处理线程问题。Multiple值表示服务对象可以在任何时候由多个线程执行。在这种情况下,您必须确保线程安全。编辑您询问在使用ConcurrencyMode.Single时使用PerCall与Single是否有任何性能提升?或者是周围的其他方式?这可能取决于服务。使用InstanceContextMode.PerCall,通过代理为每次调用创建一个新的服务实例,因此您需要处理实例创建的开销。假设您的服务构造函数不做太多事情,这将不是问题。使用InstanceContextMode.Single,在应用程序的生命周期内只存在一个服务实例,因此几乎没有与实例创建相关的开销。但是,这种模式只允许一个服务实例来处理将要进行的每个调用。因此,如果同时进行多个调用,则每个调用都必须等待其他调用完成才能执行。对于它的价值,这就是我的做法。使用具有多并发性的PerCall实例上下文。在您的WCF服务类中,创建静态成员来为您管理后端数据存储,然后根据需要使用锁定语句、易失性字段等来同步对这些静态成员的访问。这允许您的服务在保持良好状态的同时保持线程安全。我相信答案是,有多个线程(在客户端)使用同一个代理实例,因此可能允许对同一个实例进行多次调用。这篇文章有更详细的解释。如果您不在服务器上使用双向回调,InstanceContextMode.PerCall和ConcurrencyMode.Single应该没问题。在这种情况下,您将需要使用ConcurrencyMode.Reentrant,否则回调将无法访问锁定的服务实例,从而发生死锁。由于服务实例是在每次调用时创建的,因此其他线程或调用无法访问它。如另一篇回答文章中提到的文章所述,如果会话是在绑定级别创建的并且您使用相同的服务代理对象,则此类组合仍然会成为问题。因此,如果您不使用相同的代理对象或没有会话绑定,并且不对客户端使用双向回调(很可能它们应该是OneWay)InstanceContextMode.PerCall和ConcurrencyMode.Single应该没问题.我认为这完全取决于要求。如果我们想多次调用同一个服务,那么我们可以使用InstanceContextMode是Single和concurrencymode是Multiple。以上是C#学习教程:AreconcurrencyissuespossiblewhenusingWCFservicebehaviorpropertiessettoConcurrencyMode.MultipleandInstanceContextMode.PerCall?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
