Hi, I 'm having a problem with WCF callbacks that's a proper head-scratcher...
Description of setup:
There's an interface IService
that defines a WCF service. My server app implements that service in class ServiceImplementation
. The service also has a callback, defined in IServiceCallback
and implemented in the client app in class CallbackImplementation
.
At some point, the server calls SomeCallbackOperation
on the client app (that operation has [OperationContract(IsOneWay = true)]
, although I don't think it's important in this context).
The client app, as a result of receiving the callback, must do something that requires fresh information from the server. Therefore, I want as part of my callback implementation to call SomeServiceOperation
on the server.
That results in an InvalidOperationException
, which instructs me to decorate the callback implementation with CallbackBehaviorAttribute
and relax the concurrency mode. (I should mention here that the server already operates with ConcurrencyMode.Multiple
). The problem is... I do that and it doesn't work:
[CallbackBehavior(
AutomaticSessionShutdown = true,
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = false)]
public partial class CallbackImplementation : IServiceCallback {
// implementation here
}
Which has left me scratching my head. Calls continue to fail with an InvalidOperationException that says:
This operation would deadlock because the reply cannot be received until the current Message completes processing. If you want to allow out-of-order message processing, specify ConcurrencyMode of Reentrant or Multiple on CallbackBehaviorAttribute.
Question:
What can be going wrong here?
Clarification:
I fully understand what ConcurrencyMode
amounts to. I believe that, in principle, SomeCallbackOperation
can easily start a new thread pool thread that calls the server to obtain information and then uses it (such a solution would require some thread access sync mechanism for the "uses it" part). That way the problem could be solved without needing to change the ConcurrencyMode.
However, since I am forced to write the thread access sync mechanism anyway, I would prefer it if WCF at least does the ThreadPool.QueueUserWorkItem
part for me and I 'm spared the need to have an extra "async operation" method for each SomeCallbackOperation
like the one that has me stumped now.