2013-03-13 26 views
8

To pytanie jest związane z Bug in the dynamic language runtime in combination with IIS 7.5ChannelFactory bug z dynamicznym argumentów

ChannelFactory wisi gdybym dostarczenie jej poprawnie wpisane dynamicznego obiektu.

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)); 
  • Usługa powyżej jest publiczna, nie jest moja, i można przetestować ten kod siebie, czy po prostu dodać odwołanie do punktu końcowego usług przewidzianych w kodeksie;
  • StockQuoteServiceClient została utworzona przez element menu Dodaj usługę odniesienia i pobiera obiekty dynamiczne;
  • To magicznie się nie dzieje, gdy uruchamiam aplikację z F5 podczas debugowania, wszystkie linie są drukowane, a program wychodzi poprawnie;
  • Jeśli uruchomię go, a następnie załączę debugger podczas wykonywania, widzę zawieszony na wywołanie channel.GetStockQuote(src);
  • Jeśli zostanę, program pożera całą moją pamięć;
  • Zawiesza się tylko, gdy korzystam z własnego obiektu ChannelFactory z obiektami dynamicznymi, zgodnie z opisem w komentarzach.

Dlaczego mój zawiesza się, gdy pobiera dynamiczne obiekty jako parametry, gdy utworzone przez Add Service Reference działa dobrze?

+0

Korzystanie z odbicia również działa. var method = channel.GetType(). GetMethod ("GetStockQuote"); var value = (StockQuote) method.Invoke (kanał, nowy obiekt [] {src}); – lstern

Odpowiedz

3

Gdy używasz dynamicznego słowa kluczowego, każdy kod powiązany ze zmienną dynamiczną zostanie skompilowany w czasie wykonywania przez DLR. Kiedy wywołać metodę z użyciem zmiennej dynamicznej, rzeczywisty podpis metoda nie jest znany w czasie kompilacji, a także rodzaj metoda powrotu i wszystko z nim związane tworząc coś Eric Lippert nazwie "Dynamic Contagion":

„Jak wskazał ostatni raz , gdy argument wywołania jest dynamiczny , wtedy kursy są całkiem dobre, że kompilator zaklasyfikuje również wynik wywołania jako dynamiczny, taint rozprzestrzenia się, w rzeczywistości, gdy użytkownik używa prawie dowolnego operatora w dynamicznym wyrażeniu, wynikiem jest typ dynamiczny , z kilkoma wyjątkami. ("jest" na przykład zawsze zwraca a bool.) Możesz "wyleczyć" wyrażenie, aby zapobiec jego rozprzestrzenianiu się dynamizm poprzez rzutowanie go na obiekt lub na dowolny inny niedynamiczny typ: odlewania dynamiczny do obiektu jest konwersja tożsamość „.

WCF wewnętrzne wykorzystuje wiele interfejsów i abstrakcji i tam known DLR limitation dotyczące abstrakcje i interfejsy gdzie DLR nie rozwiązuje właściwego typu. (Również przyjrzeć this SO discussion)

udało mi się poprawnie wywołać ChannelFactory użyciu odbicia i oddające parametr dla innych typów (a także próbuje wywołać usługę przy użyciu niewłaściwego typu). problem może być związany DLR.

jestem nie można debugować kompilacji DLR, ale problem może być związany z "dyna mic contagion "i błąd interfejsu. W przypadku "zarażenia" każda część wywołania WCF może być kompilowana w czasie wykonywania, a błąd rozdzielczości typu może tworzyć pętle endles w niektórych przypadkach narożnych, takich jak implementacja metody nadpisanej, która wywołuje metodę bazową, a klasa podstawowa została błędnie rozstrzygnięta na to samo dziecko klasa.

Niektóre wewnętrzne podzespoły WCF wykonują dodatkowe instrukcje, gdy dołączony jest debuger (Debugger.IsAttached), który ogólnie składa się z potwierdzeń, kontroli i atrybucji. Dodatkowe instrukcje mogą dostarczyć pewnych informacji, które zabiją "dynamiczną zaraźliwość" i unikną fałszywej niekończącej się pętli.