This question is related to Bug in the dynamic language runtime in combination with IIS 7.5
ChannelFactory
hangs if I provide it with a correctly typed dynamic object.
dynamic src = "MSFT";
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress("http://www.restfulwebservices.net/wcf/StockQuoteService.svc");
var channel = new ChannelFactory<IStockQuoteService>(binding, endpoint).CreateChannel();
// this will print just fine
Console.WriteLine(channel.GetStockQuote(src as string));
// this will print just fine
Console.WriteLine(new StockQuoteServiceClient().GetStockQuote(src));
// this will never print and the application will hang with no exceptions
Console.WriteLine(channel.GetStockQuote(src));
StockQuoteServiceClient
was created by the Add Service Reference menu item and takes dynamic objects just fine;channel.GetStockQuote(src)
;ChannelFactory
with dynamic objects, as described in the comments.Why my ChannelFactory
hangs when it takes dynamic objects as parameters when the one created by Add Service Reference runs just fine?
When you use the dynamic keyword, every code related to the dynamic variable will be compiled in run-time by the DLR. When you call a method using a dynamic variable, the actual method signature is unknown in compile time and also the method return type and everything related to it creating something Eric Lippert called "Dynamic Contagion":
"As I pointed out last time, when an argument of a call is dynamic then odds are pretty good that the compiler will classify the result of the call as dynamic as well; the taint spreads. In fact, when you use almost any operator on a dynamic expression, the result is of dynamic type, with a few exceptions. ("is" for example always returns a bool.) You can "cure" an expression to prevent it spreading dynamicism by casting it to object, or to whatever other non-dynamic type you'd like; casting dynamic to object is an identity conversion."
WCF internals uses a lot of interfaces and abstractions and there's a known DLR limitation regarding abstractions and interfaces where DLR doesn't resolve the correct type. (Also take a look at this SO discussion)
I was able to correctly invoke the ChannelFactory using reflection and casting the parameter to other types (and also trying to invoke the service using the wrong type). The problem must be DLR related.
I'm unable to debug the DLR compilation but the problem may be related to the "dynamic contagion" and the interface resolution bug. With "contagion" every part of the WCF invocation may be compiled at runtime and the type resolution bug may create some endles loops in some corner cases like an overrided method implementation that invokes the base method and the base class was wrongly resolved to the same child class.
Some WCF internals executes extra instructions when the debugger is attached (Debugger.IsAttached) that extra generally consists in asserts, checks and attributions. The extra instructions may provide some information that kills the "dynamic contagion" and avoids the bogus endless loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With