.net - 带有动态参数的 ChannelFactory 错误

标签 .net wcf c#-4.0 wcf-client 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));
  • 上面的服务是公开的,不是我的,只要在代码中提供的endpoint添加服务引用就可以自己测试这段代码;
  • StockQuoteServiceClient由 Add Service Reference 菜单项创建,并采用动态对象就好了;
  • 当我在调试时使用 F5 启动应用程序时,这神奇地不会发生,所有行都打印并且程序正确退出;
  • 如果我运行它然后在执行期间附加调试器,我可以看到它卡在对 channel.GetStockQuote(src) 的调用上。 ;
  • 如果我不管它,程序会吃掉我所有的内存;
  • 只有当我使用自己的 ChannelFactory 时它才会挂起如评论中所述,使用动态对象。

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

    最佳答案

    当您使用 dynamic 关键字时,与动态变量相关的每个代码都将由 DLR 在运行时编译。当您使用动态变量调用方法时,实际的方法签名在编译时是未知的,方法返回类型以及与之相关的所有内容都会创建 Eric Lippert 称为 "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 内部使用了很多接口(interface)和抽象,有一个 known DLR limitation关于 DLR 无法解析正确类型的抽象和接口(interface)。 (另请查看 this SO discussion )

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

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

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

    关于.net - 带有动态参数的 ChannelFactory 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15376103/

    相关文章:

    c# - 以编程方式修改元数据(.net 可执行文件)

    azure - 使用自定义名称将文件保存在 DocumentDb 中

    c# - 如何从字节数组中删除字节

    c# - 强制派生类使用参数实现基类构造函数

    c# - Async CTP : Does Task. Factory.StartNew 使用 IO 完成线程?

    WCF 服务绑定(bind) wsHttp 与无需身份验证的基本绑定(bind)

    使用 SSL 的 WCF 服务

    c# - 从根节点 XML 读取值

    C# 枚举器术语困惑

    .net - C++/CLI 堆栈语义等效于 C# 的现有对象 using 语句?