2013-03-13 11 views
8

Questa domanda è legata alla Bug in the dynamic language runtime in combination with IIS 7.5bug ChannelFactory con argomenti dinamici

ChannelFactory si blocca se fornisco con un digitati correttamente oggetto dinamico.

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)); 
  • Il servizio di cui sopra è pubblico, non è mio, e si può verificare questo codice da soli se si aggiunge solo il riferimento al servizio fino al punto finale prevista nel codice;
  • StockQuoteServiceClient è stato creato dalla voce di menu Aggiungi riferimento servizio e prende gli oggetti dinamici bene;
  • Questo magicamente non accade quando lancio l'applicazione con F5 su Debug, tutte le linee vengono stampate e il programma esce correttamente;
  • Se lo eseguo e quindi allego il debugger durante l'esecuzione, posso vederlo sospeso sulla chiamata a channel.GetStockQuote(src);
  • Se lo lascio stare, il programma mangia tutta la mia memoria;
  • Si blocca solo quando utilizzo il mio ChannelFactory con oggetti dinamici, come descritto nei commenti.

Perché il mio ChannelFactory si blocca quando prende gli oggetti dinamici come parametri quando quello creato da Aggiungi servizio riferimento viene eseguito correttamente?

+0

L'uso della riflessione funziona anche. var method = channel.GetType(). GetMethod ("GetStockQuote"); var value = (StockQuote) method.Invoke (canale, nuovo oggetto [] {src}); – lstern

risposta

3

Quando si utilizza la parola chiave dinamica, ogni codice correlato alla variabile dinamica verrà compilato in fase di esecuzione dal DLR. Quando si chiama un metodo che utilizza una variabile dinamica, la firma del metodo attuale è sconosciuto in fase di compilazione e anche il tipo di ritorno del metodo e tutto ciò che riguarda lo creare qualcosa di Eric Lippert chiamato "Dynamic Contagion":

"Come ho fatto notare l'ultima volta , quando un argomento di una chiamata è dinamico allora le probabilità sono piuttosto buone che il compilatore classificherà il risultato come dinamico anche come , in cui si diffonde il taint, infatti, quando si usa un operatore qualsiasi su un'espressione dinamica, il risultato è di tipo dinamico , con alcune eccezioni. ("è" ad esempio restituisce sempre a bool.) È possibile "curare" un'espressione per impedirne la diffusione dinamicismo gettandolo in oggetto o in qualsiasi altro tipo non dinamico desiderato; fusione dinamica di oggetto è una conversione identità ".

interni WCF utilizza un sacco di interfacce e astrazioni e c'è una known DLR limitation per quanto riguarda le astrazioni e le interfacce di cui DLR non risolve il tipo corretto. (Anche dare un'occhiata a this SO discussion)

ero in grado di richiamare correttamente il ChannelFactory utilizzando la riflessione e lanciando il parametro ad altri tipi (e anche cercando di richiamare il servizio utilizzando il tipo sbagliato). il problema deve essere DLR correlate.

sono impossibile eseguire il debug della compilation DLR ma il problema potrebbe essere correlato al "dyna" mic contagion "e il bug di risoluzione dell'interfaccia. Con "contagio" ogni parte dell'invocazione di WCF può essere compilata in fase di esecuzione e il bug di risoluzione del tipo può creare alcuni loop di endle in alcuni casi angolari come un'implementazione di metodo sovrascritta che richiama il metodo base e la classe base è stata erroneamente risolta nello stesso bambino classe.

Alcuni interni WCF eseguono istruzioni aggiuntive quando il debugger è collegato (Debugger.IsAttached) che in genere consiste in asserti, assegni e attribuzioni. Le istruzioni extra possono fornire alcune informazioni che uccidono il "contagio dinamico" ed evita il loop infinito finto.

Problemi correlati