2012-12-25 16 views
7

Kann nicht nachvollziehen, warum Typkonstruktor für PerSession/WCF-Dienst zweimal aufgerufen wurde. ConcurrencyMode ist Multiple. Starten Sie fünf gleichzeitige Clients, die den gleichen WCF-Service-Methodenaufruf tun, in einem Protokoll sehe ich, dass static Konstruktor wurde zweimal aufgerufen, das erste Mal und nach 3 Sekunden zum zweiten Mal mit einem anderen ProcessId/ThreadId. Keine Ausnahmen weder im Konstruktor selbst noch in den WCF-Trace-Protokollen. Die Ausführungszeit des Konstruktors beträgt ~ 10 Millisekunden gemäß Protokoll. Dies führt dazu, dass alle statischen Felder nicht wie erwartet zwischen allen Dienstinstanzen geteilt werden, und im Falle von 5 Clientverbindungen habe ich 5 Dienste und zwei verschiedene statische Kontexte, so dass die Änderung in einem statischen Feld nicht für alle Dienste reflektiert wird.Statischer Konstruktor, der zweimal für PerSession WCF-Dienst aufgerufen wird

Dieses Problem verwirrt viele Dinge, da ich auf einige statische Caches angewiesen bin, die über mehrere Dienstinstanzen verteilt sind.

Der Dienst wird in IIS gehostet. Es wird kein IIS neu gestartet, AppPool wird in diesem Zeitintervall wiederverwendet.

[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

Wenn Ihr Ziel ist sicherzustellen, dass nur eine Instanz erstellt wird, möchten Sie möglicherweise Singleton-Muster für diese Klasse implementieren: http://en.wikipedia.org/wiki/Singleton_pattern – Nogard

+2

@Nogard und das wird so völlig nutzlos in diesem sein Fall, da IIS mehrere Instanzen des Programms öffnet, die alle glücklich sind, ihren eigenen Singleton zu haben. Statische Konstruktoren werden auch als ONLY ON CLASS LOAD DEFINIERT bezeichnet. Dies hält den Benutzer jedoch nicht davon ab, separate Anwendungsdomänen zu verwenden, die die Klassen separat laden, wie dies bei IIS der Fall ist. – TomTom

Antwort

6

Vorausgesetzt, dass Sie Ihren Service mit IIS hosten, das ist ein normales Verhalten, wenn Sie explizit den Prozess so konfigurieren, dass nur aus einer einzigen AppDomain erlauben gesponnen werden.

Wenn Sie sich die Liste der laufenden Prozesse ansehen, finden Sie, dass jede Prozess-ID in Ihrem Protokoll einer Kopie von w3wp.exe entspricht, die eine separate App-Domäne hostet.

+0

Sie haben Recht, dies ist der von IIS gehostete Dienst. Vergaß dies zu erwähnen. Nur aktualisierte Frage. Kann ich einzelnes 'AppDomain'-Verhalten nur für einen bestimmten WCF-Dienst einrichten? Da sind auch andere Dienste, so dass ich nichts anderes verderben möchte – sll

+0

Ich hatte 2 Worker Prozesse pro AppPool, nach dem Wechsel zu '1' everything funktioniert gut bis jetzt, sowieso schätzen jeden Hinweis in Bezug explizit anzugeben, alle WCF-Instanzen zu hosten der gleiche Prozess – sll

Verwandte Themen