【问题标题】:ChannelFactory bug with dynamic arguments带有动态参数的 ChannelFactory 错误
【发布时间】:2013-02-28 20:15:33
【问题描述】:

此问题与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));
  • 上面的服务是公开的,不是我的,只要在代码中提供的endpoint添加服务引用就可以自己测试这段代码;
  • StockQuoteServiceClient 由“添加服务引用”菜单项创建,可以很好地获取动态对象;
  • 当我在调试时使用 F5 启动应用程序时,这神奇地不会发生,所有行都打印并且程序正确退出;
  • 如果我运行它,然后在执行期间附加调试器,我可以看到它挂在对 channel.GetStockQuote(src) 的调用上;
  • 如果我不管它,程序会吃掉我所有的记忆;
  • 仅当我将自己的 ChannelFactory 与动态对象一起使用时,它才会挂起,如 cmets 中所述。

为什么我的ChannelFactory 在通过添加服务引用创建的对象运行良好时将动态对象作为参数时挂起?

【问题讨论】:

  • 使用反射也可以。 var method = channel.GetType().GetMethod("GetStockQuote"); var value = (StockQuote)method.Invoke(channel, new object[] { src });

标签: .net wcf c#-4.0 wcf-client channelfactory


【解决方案1】:

当您使用动态关键字时,与动态变量相关的每个代码都将由 DLR 在运行时编译。当您使用动态变量调用方法时,实际的方法签名在编译时是未知的,方法返回类型以及与之相关的所有内容都会创建 Eric Lippert 称为 "Dynamic Contagion" 的东西:

“正如我上次指出的,当调用的参数是动态的 那么编译器会对结果进行分类的可能性很大 通话也是动态的;污染蔓延。事实上,当你 在动态表达式上使用几乎任何运算符,结果是 动态类型,有少数例外。 (例如,“is”总是返回 一个布尔值。)您可以“治愈”一个表达式以防止它传播 通过将其投射到对象或任何其他非动态的动态主义 输入你想要的;将动态转换为对象是一种身份转换。”

WCF 内部使用大量接口和抽象,并且有一个known DLR limitation 关于 DLR 无法解析正确类型的抽象和接口。 (也可以看看this SO discussion

我能够使用反射正确调用 ChannelFactory 并将参数转换为其他类型(并且还尝试使用错误的类型调用服务)。该问题必须与 DLR 相关。

我无法调试 DLR 编译,但问题可能与“动态传染”和接口解析错误有关。使用“传染”,WCF 调用的每个部分都可能在运行时编译,并且类型解析错误可能会在某些极端情况下创建一些 endles 循环,例如调用基方法的重写方法实现,而基类被错误地解析为同一个孩子类。

当附加调试器 (Debugger.IsAttached) 时,一些 WCF 内部会执行额外的指令,这些指令通常包含在断言、检查和属性中。额外的指令可能会提供一些信息来杀死“动态传染”并避免虚假的无限循环。

【讨论】:

    猜你喜欢
    • 2013-05-18
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2019-05-04
    相关资源
    最近更新 更多