2013-03-13 83 views
8

的ChannelFactory错误这个问题是关系到Bug in the dynamic language runtime in combination with IIS 7.5动态参数

ChannelFactory挂起,如果我给它提供一个正确类型的动态对象。

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由添加服务引用菜单项创建并采用动态对象就好了;
  • 当我使用F5在Debug上启动应用程序时,这奇迹般地不会发生,所有行都会打印并且程序正常退出;
  • 如果我运行它,然后在执行过程中附加调试器,我可以看到它挂在channel.GetStockQuote(src)的调用上;
  • 如果我离开它,程序会吃掉我所有的记忆;
  • 只有当我使用我自己的ChannelFactory和动态对象时才会挂起,如注释中所述。

为什么我的ChannelFactory以动态对象作为参数时挂起,当添加服务引用创建的运行正常时?

+0

使用反射也可以。 var method = channel.GetType()。GetMethod(“GetStockQuote”); var value =(StockQuote)method.Invoke(channel,new object [] {src}); – lstern 2013-05-19 20:20:43

回答

3

当您使用动态关键字时,与动态变量相关的每个代码都将在运行时由DLR进行编译。当你调用使用动态变量的方法,实际的方法签名是在编译时未知的,也是方法的返回类型和一切与之相关的创造一些埃里克利珀称为"Dynamic Contagion"

“正如我指出的最后一次,当一个调用的参数是动态的 然后几率是相当不错的,编译器会将调用的结果 也分类为动态的;事件传播。事实上,当您在动态表达式上几乎使用任何运算符时,结果是 动态类型,但有一些例外(例如,“is”总是返回 a布尔值。)您可以“治愈”一个表达式以防止它传播 通过将其转换为对象或其他任何非动态 类型来实现动态化;铸造动态到对象身份的转换。”

WCF内部采用了大量的接口和抽象和有关于抽象和接口,其中DLR不能解决正确类型known DLR limitation。(也看一看this SO discussion

我能够使用反射和铸造参数到其他类型的(并且也尝试使用了错误的类型来调用服务)。这个问题必须DLR相关正确地调用的ChannelFactory。

我无法调试DLR编译,但问题可能与“dyna”有关麦克风感染“和接口解析错误。对于“传染”,WCF调用的每个部分都可能在运行时被编译,并且类型解析错误可能会在某些角落案例中创建一些endles循环,如调用基本方法的overrided方法实现,并且基类被错误地解析为同一个孩子类。

某些WCF内部在附加调试器时会执行额外的指令(Debugger.IsAttached),额外的指令通常包含在断言,检查和归因中。额外的说明可能会提供一些消除“动态传染”的信息,并避免虚假的无限循环。