Share via


Avoiding OneWay Deadlocks

I have two web services and I'm seeing a deadlock when making calls between them. The operation calls are marked as OneWay. How do I fix this? And, how is it even possible for one-way calls to block?

Marking an operation with the OneWay attribute doesn't offer any magical protection against deadlocks. The OneWay attribute means that in messaging terms, there is no application data that the service is expected to return as a result of the call. However, one-way calls still need to wait for the service to accept transmission of the message. A one-way call is complete when the service acknowledges that the message has successfully arrived (although the definition of successful can vary a bit). We've seen this before in HTTP, where successful acknowledgement takes the form of a 202 Accepted response.

There's a number of reasons then why a service might appear to have deadlocked. The service could simply be really slow and has either not accepted the connection or not finished processing to the point where it can send the acknowledgement. Now that you know that the one-way call can block, it takes more sleuthing before you can declare that a deadlock is taking place. The operation call could be held in limbo for a while because of the ConcurrencyMode setting. Setting ConcurrencyMode to Single prevents the service from taking a second call in while an existing call is underway. The operation call could also be waiting for the SynchronizationContext to become free. Basically, the problem with the one-way call could be almost any of the problems that you'd associate with a standard bidirectional call. Applying OneWay attributes to your calls does not get you out of having to debug your service deadlocks.

Next time: How HostNameComparisonMode Works