2013-03-13 86 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),額外的指令通常包含在斷言,檢查和歸因中。額外的說明可能會提供一些消除「動態傳染」的信息,並避免虛假的無限循環。