2012-12-25 12 views
7

Nie można udnerstand, dlaczego konstruktor type dla usługi PerSession/WCF był wywoływanie dwa razy. ConcurrencyMode to Multiple. Wystarczy uruchomić pięć równoczesnych klientów, którzy wykonują to samo wywołanie metody usługi WCF, w dzienniku widzę, że konstruktor static został wywołany dwa razy, pierwszy raz i po 3 sekundach drugi raz z innym ProcessId/ThreadId. Brak wyjątków ani w dzienniku konstruktora, ani w dziennikach śledzenia WCF. Czas wykonania konstruktora wynosi ~ 10 milisekund według dziennika. To powoduje, że wszystkie statyczne pola nie są współużytkowane przez wszystkie instancje usług, jak przypuszczano, aw przypadku 5 połączeń klienckich mam 5 usług i dwa różne statyczne konteksty, więc zmiana w statycznym polu nie jest odzwierciedlana dla wszystkich usług.Konstruktor statyczny wywołany dwukrotnie dla usługi WCF PerSession

To wydanie może dezorientować wiele rzeczy, ponieważ polegam na statycznych pamięciach podręcznych współużytkowanych w wielu instancjach usług.

Usługa jest hostowana pod numerem IIS. Bez ponownego uruchamiania usług IIS, AppPool przetwarza w tym przedziale czasu.

[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(
    InstanceContextMode = InstanceContextMode.PerSession, 
    IncludeExceptionDetailInFaults = true, 
    ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class WcfService 
{ 
    private static readonly ILog logger; 
    private static volatile bool typeInitialized; 

    static WcfService() 
    { 
     try 
     { 
      // Here is typeInitialized is false in both calls 
      logger = LogManager.GetLogger("LogName"); 

      logger.InfoFormat("[PID:{0}] [THID:{1}] BEGIN Static constructor", 
       Process.GetCurrentProcess().Id, 
       Thread.CurrentThread.ManagedThreadId); 
     } 
     catch (Exception exception) 
     { 
      logger.Error("error on type construction stage", exception); 
     } 
     finally 
     { 
      logger.InfoFormat("[PID:{0}] [THID:{1}] END Static constructor", 
       Process.GetCurrentProcess().Id, 
       Thread.CurrentThread.ManagedThreadId);    
      typeInitialized = true; 
     } 
    } 
} 
+0

Jeśli Twoim celem jest zapewnienie utworzenia tylko jednej instancji, możesz chcieć zaimplementować wzorzec Singleton dla tej klasy: http://en.wikipedia.org/wiki/Singleton_pattern – Nogard

+2

@Nogard i będzie to całkowicie bezużyteczne w tym przypadku, gdy IIS otwiera wiele wystąpień programu, które wszyscy są zadowoleni z posiadania własnego singleton. Konstruktory statyczne są również ZDEFINIOWANE jako nazywane TYLKO RAZEM NA OBCIĄŻENIE KLASY - ale to nie powstrzymuje użytkownika od posiadania oddzielnych aplikacji, które ładują klasy oddzielnie, tak jak w przypadku usług IIS. – TomTom

Odpowiedz

6

Zakładając jesteś hosting usługi IIS, jest to normalne zachowanie, chyba że wyraźnie skonfigurować proces tylko pozwolić jeden AppDomain przed rozkręcać.

Jeśli spojrzysz na listę uruchomionych procesów, każdy identyfikator procesu w dzienniku odpowiada kopii pliku w3wp.exe, w którym znajduje się osobne domena aplikacji.

+0

Masz rację, to usługa hostowana w IIS. Zapomniałem o tym wspomnieć. Właśnie zaktualizowane pytanie. Czy mogę skonfigurować pojedyncze zachowanie 'AppDomain' tylko dla określonej usługi WCF? Ponieważ dookoła są inne usługi, więc nie chcę zepsuć niczego innego – sll

+0

Miałem 2 procesy robocze na AppPool, po zmianie na "1" wszystko działało dobrze do tej pory, i tak doceniam wszelkie rady dotyczące jawnego określania hostowania wszystkich instancji WCf w ten sam proces – sll