Instances and Concurrent Access

Using the same proxy, a single client can issue multiple concurrent calls to a service. The client can use multiple threads to invoke calls on the service, or it can issue one-way calls in rapid succession on the same thread. In both of these cases, whether the calls from the same client are processed concurrently is the product of the service's configured instancing mode, the service's concurrency mode, and the configured delivery mode (that is, the transport session). The following discussion applies equally to request-reply and one-way calls.

Per-Call Services

In the case of a per-call service, if there is no transport-level session, concurrent processing of calls is allowed. Calls are dispatched as they arrive, each to a new instance, and execute concurrently. This is the case regardless of the service concurrency mode. I consider this to be the correct behavior.

If the per-call service has a transport-level session, whether concurrent processing of calls is allowed is a product of the service concurrency mode. If the service is configured with ConcurrencyMode.Single, concurrent processing of the pending calls is not allowed, and the calls are dispatched one at a time. The reason is that with ConcurrencyMode.Single WCF tries to maintain the guarantee of the transport session that messages are processed strictly in the order in which they were received in that session by having exactly one outstanding instance per channel. You should avoid lengthy processing of calls, because it may risk call timeouts.

While this is a direct result of the channel's architecture, I consider this to be a flawed design. If the service is configured with ConcurrencyMode.Multiple, concurrent processing is allowed. Calls are dispatched as they arrive, each to a new instance, and execute concurrently. An interesting observation here is that in the interest of throughput, it is a good idea to configure a per-call service with ConcurrencyMode.Multiple—the instance itself will still be thread-safe (so you will not incur the synchronization liability), yet you will allow concurrent calls from the same client.

Tip

Two clients using two different proxies will have two distinct channels and will have no issue with concurrent calls. It is only concurrent calls on the same transport session that are serialized one at a time to the per-call service.

When the service is configured with ConcurrencyMode.Reentrant, if the service does not call out, it behaves similarly to a service configured with ConcurrencyMode.Single. If the service does call out, the next call is allowed in, and the returning call has to negotiate the lock like all other pending calls.

Sessionful and Singleton Services

In the case of a sessionful or a singleton service, the configured concurrency mode alone governs the concurrent execution of pending calls. If the service is configured with ConcurrencyMode.Single, calls will be dispatched to the service instance one at a time, and pending calls will be placed in a queue. You should avoid lengthy processing of calls, because it may risk call timeouts.

If the service instance is configured with ConcurrencyMode.Multiple, concurrent processing of calls from the same client is allowed. Calls will be executed by the service instance as fast as they come off the channel (up to the throttle limit). Of course, as is always the case with a stateful unsynchronized service instance, you must synchronize access to the service instance or risk state corruption.

If the service instance is configured with ConcurrencyMode.Reentrant, it behaves just as it would with ConcurrencyMode.Single. However, if the service calls out, the next call is allowed to execute. You must follow the guidelines discussed previously regarding programming in a reentrant environment.

Tip

For a per-session service configured with ConcurrencyMode.Multiple to experience concurrent calls, the client must use multiple worker threads to access the same proxy instance. However, if the client threads rely on the auto-open feature of the proxy (that is, just invoking a method and having that call open the proxy if the proxy is not yet open) and call the proxy concurrently, then the calls will actually be serialized until the proxy is opened, and will be concurrent after that. If you want to dispatch concurrent calls regardless of the state of the proxy, the client needs to explicitly open the proxy (by calling the Open( ) method) before issuing any calls on the worker threads.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.240.119