Well, I think I discussed this.
WCF uses single-threaded by default. All calls and callbacks are combined into a single thread (or SynchronizationContext, to be more precise).
My application is a single-threaded WPF application, so the SynchronizationContext is set to the send stream.
When the callback arrives, it tries to transfer the call to the send stream, which, of course, is blocked during the initial call to the service. I don’t understand that this is locked for sure, but obviously there is a global lock that he is trying to get before waiting for the sending stream.
When the send thread then calls the service again, it blocks this global lock.
Two ways:
1) Create a service proxy in another thread. All calls will be processed through this thread instead, and it does not matter that the send thread is blocked.
2) Apply the [CallbackBehavior (UseSynchronizationContext = false)] attribute to the client class that implements the callback. This means that WCF ignores the synchronization context when the callback arrives, and it will serve it in any available thread.
I went with 2. Obviously, this means I need to mobilize callbacks that could update the GUI for the send thread myself, but fortunately my callback implementation is a small shell, so I just do _dispatcher.BeginInvoke ( ) in each callback method for Marshal ASYNCHRONOUSLY. Then the sending stream will be serviced when it gets the chance that I wanted in the first place.
GazTheDestroyer
source share