I haven't seen this answered yet, pretty simple setup...
Question: I'm getting a deadlock, I want to know how to avoid it, given my setup.
I have ServiceA, which implements IServiceA, and ServiceB, which implements IServiceB. Both services are marked as "perSession" and "re-entrant"...
IServiceA supports this method:
DataA GetDataA( );
IServiceB supports this method:
DataB GetDataB( );
in my app, I call ServiceA's GetDataA( )
method, and inside ServiceA's GetDataA method, it opens up a proxy connection to ServiceB, and calls GetDataB( )
.
GetDataB on the service end (not the client's end) executes correctly (debug log says so) but when it tries to return the data to ServiceA, it deadlocks.
I'm assuming this is because when I called into ServiceA from "user", it obtained the IO completion port "delivery lock" (or perhaps it's called the WCF per-session" lock. In any case, a lock is taken. I'm assuming that when ServiceB's GetDataB( )
is attempting to return the value, what's it's really done is flipped around the channel and is trying to call a receive method on ServiceA, which needs the lock and deadlocks.
in every question I've read so far where people ask "is it okay to chain one service from another", every (stupid) answer has been, "sure! go ahead! nothing to it! services don't know if they're being called by normal .NET code or if they're being called from another service!". Annoying. There certainly "is something to it", even if it's a little tiny bit trivial.
I've read that I can't mark methods that return values as "one way". And marking them as "re-entrant"... should that work or not? I know if in my service, I call a callback, the lock is silently released. What if I call another service? is WCF smart enough to release the lock in that case as well?
I could go mark my services as "multiple" instead of "re-entrant", but I'm wondering (a) is the deadlock really from what I think it is, or could it be from something else, and (b) is there a better way around this?