使用WCF服务行为属性设置为ConcurrencyMode.Multiple和I​​nstanceContextMode.PerCall当并发问题可能吗? [英] Are concurrency issues possible when using the WCF Service Behavior attribute set to ConcurrencyMode.Multiple and InstanceContextMode.PerCall?

查看:327
本文介绍了使用WCF服务行为属性设置为ConcurrencyMode.Multiple和I​​nstanceContextMode.PerCall当并发问题可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个WCF服务,使一个很好的协议的事务NHibernate的来电。有时我们看到SQL超时,即使在通话中更新不同的行和表被设置为行级锁。

We have a WCF service that makes a good deal of transactional NHibernate calls. Occasionally we were seeing SQL timeouts, even though the calls were updating different rows and the tables were set to row level locking.

挖入日志后,它看起来像不同线程是(用块我们的交易)中的代码输入相同的点,并且更新挂在提交。它没有任何意义,但是,因为我们认为,以下服务类属性被强迫每个服务呼叫的唯一执行线程:

After digging into the logs, it looks like different threads were entering the same point in the code (our transaction using block), and an update was hanging on commit. It didn't make sense, though, because we believed that the following service class attribute was forcing a unique execution thread per service call:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]

我们最近改变并发模式 ConcurrencyMode.Single ,还没有遇到任何问题,但缺陷是很难复制的(如果任何人有冲洗这样的错误有什么想法!出去,让我知道)

We recently changed the concurrency mode to ConcurrencyMode.Single and haven't yet run into any issues, but the bug was very difficult to reproduce (if anyone has any thoughts on flushing a bug like that out, let me know!).

总之,所有使我想到我的问题:不应PerCall的InstanceContextMode执行服务中的线程安全的,即使该ConcurrencyMode设置为多个?怎么会是可能的两次调用相同的服务实例进行服务?

Anyway, that all brings me to my question: shouldn't an InstanceContextMode of PerCall enforce thread-safety within the service, even if the ConcurrencyMode is set to multiple? How would it be possible for two calls to be serviced by the same service instance?

谢谢!

推荐答案

有两种不同的WCF客户端,即代理,引用您的WCF服务的同一个实例的唯一方法是使用 InstanceContextMode = InstanceContextMode.Single 。这是,如果比例是一个问题,一个糟糕的选择,所以你要使用 PerCall 如果你能。

The only way to have two different WCF clients, i.e., proxies, reference the same instance of your WCF service is to use InstanceContextMode=InstanceContextMode.Single. This is a poor choice if scaling is an issue, so you want to use PerCall if you can.

当您使用 PerCall 每个拨打以WCF服务都有自己的WCF服务实例的。没有共享服务实例的,但是这并不意味着它们不共享同一后端存储(例如,数据库,存储器,文件等)。只要记住, PerCall 允许每个 呼叫可同时访问WCF服务。

When you use PerCall, each CALL to the WCF service gets its own WCF service instance. There's no sharing of the service instance, but that doesn't mean that they don't share the same back-end storage (e.g., database, memory, file, etc.). Just remember, PerCall allows each call to access your WCF service simultaneously.

ConcurrencyMode 设置控制服务本身的线程模型。 的设置限制所有的WCF服务实例的同一线程上运行。所以,如果你有在同一时间连接多个客户端,它们将只在在WCF服务端一次执行一条。在这种情况下,您可以利用WCF提供同步。它会工作得很好,因为你所看到的,但认为这是其只能通过同步宏观层面的控制 - 每WCF服务呼叫将被全部下一次调用可以执行之前执行

The ConcurrencyMode setting controls the threading model of the service itself. A setting of Single restricts all of the WCF service instances to running on the same thread. So if you have multiple clients connecting at the same time, they will only be executed one at a time on the WCF service side. In this case, you leverage WCF to provide synchronization. It'll work fine, as you have seen, but think of this as having only macro-level control over synchronization - each WCF service call will execute in its entirety before the next call can execute.

设置 ConcurrencyMode ,但是,将允许所有的WCF服务实例同时运行。在这种情况下,的你是负责提供必要的同步的。把这看作有过同步,因为你可以只同步每个需要同步调用的那部分微观层面的控制。

Setting ConcurrencyMode to Multiple, however, will allow all of the WCF service instances to execute simultaneously. In this case, you are responsible for providing the necessary synchronization. Think of this as having micro-level control over synchronization since you can synchronize only those portions of each call that need to be synchronized.

我希望我已经很好地解释这个够了,但这里的MSDN文档为 ConcurrencyMode一个片段 以防万一:

I hope I've explained this well enough, but here's a snippet of the MSDN documentation for ConcurrencyMode just in case:

设置ConcurrencyMode为单指示系统限制
该服务执行一个线程
的时间,从而释放
你处理线程
问题的实例。即
的服务对象的多个装置的一个值可以通过
多个线程在任何一个时间被执行。在
这种情况下,你必须确保线程
安全。

Setting ConcurrencyMode to Single instructs the system to restrict instances of the service to one thread of execution at a time, which frees you from dealing with threading issues. A value of Multiple means that service objects can be executed by multiple threads at any one time. In this case, you must ensure thread safety.

修改

您询问

是否有任何性能提升,然后使用PerCall主场迎战使用ConcurrencyMode.Single时单?或者是逆真的吗?

Is there any performance increase, then, using PerCall vs. Single when using ConcurrencyMode.Single? Or is the inverse true?

这将可能是服务相关的。

This will likely be service dependent.

InstanceContextMode.PerCall ,新的服务实例为每个并通过代理每次调用创建的,所以你必须实例创建的开销来处理。假设你的服务的构造函数没有做太多,这会不会是一个问题。

With InstanceContextMode.PerCall, a new service instance is created for each and every call via the proxy, so you have the overhead of instance creation to deal with. Assuming your service constructor doesn't do much, this won't be a problem.

通过 InstanceContextMode.Single ,只有一个服务实例存在应用程序的生命周期,所以与创建实例相关的几乎没有开销。然而,这种模式只允许一个服务实例来处理这将不会进行每次呼叫。因此,如果你有多个呼叫正在同时进行,每次通话将不得不等待其他通话结束后才能执行它。

With InstanceContextMode.Single, only one service instance exists for the lifetime of the application, so there is practically no overhead associated with instance creation. However, this mode allows only one service instance to process every call that will ever be made. Thus, if you have multiple calls being made simultaneously, each call will have to wait for the other calls to finish before it can be executed.

有关它的价值,这里的我是如何做到这一点。使用带有并发的 PerCall 实例上下文。内部WCF服务类,创建静态成员管理后端数据存储为你,然后用锁定语句,<$根据需要同步访问这些静态成员C $ C>挥发性领域等,这让你的服务扩展很好,同时仍保持线程安全的。

For what it's worth, here's how I've done this. Use the PerCall instance context with Multiple concurrency. Inside your WCF service class, create static members to manage the back-end data store for you, and then synchronize access to these static members as necessary using the lock statement, volatile fields, etc. This allows your service to scale nicely while still maintaining thread safety.

这篇关于使用WCF服务行为属性设置为ConcurrencyMode.Multiple和I​​nstanceContextMode.PerCall当并发问题可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆