Sitzungen, Instanziierung und Parallelität

Eine Sitzung ist die Korrelation (d. h. die Beziehung) aller zwischen zwei Endpunkten gesendeter Nachrichten. Instanziierung bezieht sich auf die Steuerung der Lebensdauer von benutzerdefinierten Dienstobjekten und den zugehörigen InstanceContext-Objekten. Parallelität bezeichnet die Kontrolle der Anzahl von Threads, die gleichzeitig in einem InstanceContext ausgeführt werden.

In diesem Thema werden diese Einstellungen, ihre Verwendung und die Interaktion zwischen den Einstellungen beschrieben.

Sitzungen

Wenn die System.ServiceModel.ServiceContractAttribute.SessionMode-Eigenschaft durch einen Dienstvertrag auf System.ServiceModel.SessionMode.Required festgelegt wird, bedeutet dies, dass alle Aufrufe (das heißt der zugrunde liegende Nachrichtenaustausch, durch den die Aufrufe unterstützt werden) Teil derselben Konversation sein müssen. Falls in einem Vertrag angegeben wird, dass Sitzungen zwar erlaubt, aber nicht erforderlich sind, können Clients eine Verbindung herstellen und eine Sitzung aufbauen oder auch nicht. Wird eine Sitzung beendet und eine Nachricht über diesen sitzungsbasierten Kanal gesendet, wird eine Ausnahme ausgelöst.

Bei WCF-Sitzungen finden sich die folgenden Hauptkonzepte:

  • Sie werden explizit von der aufrufenden Anwendung initiiert und beendet.
  • Die während einer Sitzung gesendeten Nachrichten werden in der Reihenfolge verarbeitet, in der sie empfangen wurden.
  • Durch Sitzungen wird eine Gruppe von Nachrichten zu einer Konversation zusammengefasst. Diese Korrelation ist jedoch abstrakt. So werden zum Beispiel bei einem sitzungsbasierten Kanal Nachrichten auf Grundlage einer gemeinsamen Netzwerkverbindung zueinander in Beziehung gesetzt, bei einem anderen Kanal geschieht dies wiederum auf Grundlage eines gemeinsamen Tags im Nachrichtentext. Die Features, die von der Sitzung abgeleitet werden können, sind abhängig von der Art der Korrelation.
  • Einer WCF-Sitzung ist kein allgemeiner Datenspeicher zugeordnet.

Falls Sie mit der System.Web.SessionState.HttpSessionState-Klasse und den von ihr bereitgestellten Funktionen in ASP.NET-Anwendungen vertraut sind, fallen Ihnen möglicherweise die folgenden Unterschiede zwischen dieser Art von Sitzung und einer WCF-Sitzung auf:

  • ASP.NET-Sitzungen werden immer vom Server initiiert.
  • ASP.NET-Sitzungen sind implizit nicht sortiert.
  • ASP.NET-Sitzungen stellen einen allgemeinen Datenspeicher für Anforderungen bereit.

Client- und Dienstanwendungen interagieren auf unterschiedliche Weise mit Sitzungen. Clientanwendungen initiieren Sitzungen und empfangen und verarbeiten dann die innerhalb der Sitzung gesendeten Nachrichten. Dienstanwendungen können Sitzungen als Erweiterungspunkt verwenden, um zusätzliches Verhalten hinzuzufügen. Dies geschieht durch direkte Nutzung von InstanceContext oder durch Implementierung eines benutzerspezifischen Instanzenkontextanbieters.

Instanziierung

Durch das Instanziierungsverhalten (das über die System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode-Eigenschaft festgelegt wird) lässt sich steuern, wie der InstanceContext als Antwort auf eingehende Nachrichten erstellt wird. Standardmäßig ist jeder InstanceContext einem benutzerdefinierten Dienstobjekt zugeordnet. Dies bedeutet, dass (im Normalfall) auch die Instanziierung benutzerdefinierter Dienstobjekte über die InstanceContextMode-Eigenschaft gesteuert wird. Die InstanceContextMode-Enumeration definiert die Instanziierungsmodi.

Es stehen die folgenden Instanziierungsmodi zur Verfügung:

  • PerCall: Für jede Clientanforderung wird ein neuer InstanceContext (und damit auch ein neues Dienstobjekt) erstellt.
  • PerSession: Für jede neue Clientsitzung wird ein neuer InstanceContext (und damit auch ein neues Dienstobjekt) erstellt und für die Lebensdauer dieser Sitzung aufrechterhalten, wofür eine Bindung erforderlich ist, die Sitzungen unterstützt.
  • Single: Alle Clientanforderungen werden während der Lebensdauer der Anwendung von einem InstanceContext (und damit einem Dienstobjekt) verarbeitet.

Das folgende Codebeispiel zeigt den Standard-InstanceContextMode-Wert (PerSession), der explizit für eine Dienstklasse festgelegt wird.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)] 
public class CalculatorService : ICalculatorInstance 
{ 
    …
}

Durch die System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode-Eigenschaft wird gesteuert, wie oft der InstanceContext freigegeben wird. Die System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode-Eigenschaft und die System.ServiceModel.ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete-Eigenschaft bestimmen dagegen, wann das Dienstobjekt freigegeben wird.

Bekannte Singleton-Dienste

Gelegentlich ist eine Variante für einzelne Instanzendienstobjekte nützlich: Sie können selbst ein Dienstobjekt und den Diensthost, der dieses Objekt verwendet, erstellen. Hierfür müssen Sie auch die System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode-Eigenschaft auf Single festlegen, damit keine Ausnahme ausgelöst wird, sobald der Diensthost geöffnet wird.

Verwenden Sie zum Erstellen eines solchen Diensts den System.ServiceModel.ServiceHost.#ctor(System.Object,System.Uri[])-Konstruktor. Dieser ist eine Alternative zur Implementierung eines benutzerspezifischen System.ServiceModel.Dispatcher.IInstanceContextInitializer, wenn Sie eine bestimmte Objektinstanz für einen Singleton-Dienst bereitstellen möchten. Sie können diese Alternative verwenden, wenn Ihr Dienstimplementierungstyp schwer zu erstellen ist (wenn er z. B. keinen öffentlichen parameterlosen Standardkonstruktor implementiert).

Beachten Sie, dass einige Funktionen im Zusammenhang mit dem Windows Communication Foundation (WCF)-Instanziierungsverhalten anders arbeiten, wenn ein Objekt für diesen Konstruktor bereitgestellt wird. So zeigt zum Beispiel der Aufruf von System.ServiceModel.InstanceContext.ReleaseServiceInstance keine Wirkung, wenn eine Singleton-Objektinstanz bereitgestellt wird. Dementsprechend werden auch alle anderen Instanzfreigabemechanismen ignoriert. Der ServiceHost verhält sich immer so, als ob die System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode-Eigenschaft für alle Vorgänge auf System.ServiceModel.ReleaseInstanceMode.None festgelegt ist.

Freigeben von InstanceContext-Objekten

Sie können auch steuern, welcher sitzungsbasierte Kanal oder Aufruf dem InstanceContext-Objekt zugeordnet wird, indem Sie diese Zuordnung selbst vornehmen. Ein vollständiges Beispiel finden Sie unter InstanceContextSharing.

Parallelität

Bei der Parallelität handelt es sich um die Steuerung der Anzahl von Threads, die gleichzeitig in einem InstanceContext aktiv sind. Sie können diese Anzahl über System.ServiceModel.ServiceBehaviorAttribute.ConcurrencyMode in Verbindung mit der ConcurrencyMode-Enumeration bestimmen.

Es stehen die folgenden drei Parallelitätsmodi zur Verfügung:

  • Single: Jeder Instanzkontext darf höchstens über jeweils einen Thread verfügen, der im Instanzkontext Nachrichten verarbeitet. Falls weitere Threads diesen Instanzkontext verwenden möchten, werden sie so lange blockiert, bis der ursprüngliche Thread den Instanzkontext verlässt.
  • Multiple: Jede Dienstinstanz kann über mehrere Threads verfügen, die Nachrichten gleichzeitig verarbeiten. Für diesen Parallelitätsmodus muss die Dienstimplementierung threadsicher sein.
  • Reentrant: Jede Dienstinstanz verarbeitet jeweils nur eine Nachricht, akzeptiert jedoch eintrittsinvariante Aufrufe. Der Dienst akzeptiert diese Aufrufe nur dann, wenn der Aufruf über ein WCF-Clientobjekt erfolgt.

Tipp

Das Schreiben von Code, bei dem problemlos mehr als ein Thread verwendet wird, kann sich als sehr schwierig erweisen. Stellen Sie sicher, dass Ihr Dienst ordnungsgemäß mit den Modi Multiple bzw. Reentrant arbeiten kann, bevor Sie diese Werte verwenden. Weitere Informationen finden Sie unter ConcurrencyMode.

Die Parallelität steht mit dem Instanziierungsmodus in Beziehung. Bei der PerCall-Instanziierung ist die Parallelität nicht relevant, da jede Nachricht von einem neuen InstanceContext verarbeitet wird und daher nie mehr als ein Thread im InstanceContext aktiv ist.

Das folgende Codebeispiel zeigt, wie die ConcurrencyMode-Eigenschaft auf den Wert Multiple festgelegt wird.

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] 
public class CalculatorService : ICalculatorConcurrency 
{ 
    …
}

Interaktion von Sitzungen und InstanceContext-Einstellungen

Sitzungen und der InstanceContext interagieren je nach Kombination des Werts der SessionMode-Enumeration in einem Vertrag und der System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode-Eigenschaft der Dienstimplementierung, durch die die Zuordnung zwischen Kanälen und bestimmten Dienstobjekten gesteuert wird.

Die folgende Tabelle enthält eine Übersicht über die Ergebnisse eines eingehenden Kanals, der Sitzungen je nach Kombination der Werte für die System.ServiceModel.ServiceContractAttribute.SessionMode-Eigenschaft und die System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode-Eigenschaft eines Diensts unterstützt oder nicht unterstützt.

InstanceContextMode-Wert Required Allowed NotAllowed

PerCall

  • Verhalten bei sitzungsbasiertem Kanal: Eine Sitzung und ein InstanceContext pro Aufruf.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Eine Ausnahme wird ausgelöst.
  • Verhalten bei sitzungsbasiertem Kanal: Eine Sitzung und ein InstanceContext pro Aufruf.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Ein InstanceContext pro Aufruf.
  • Verhalten bei sitzungsbasiertem Kanal: Eine Ausnahme wird ausgelöst.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Ein InstanceContext pro Aufruf.

PerSession

  • Verhalten bei sitzungsbasiertem Kanal: Eine Sitzung und ein InstanceContext pro Kanal.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Eine Ausnahme wird ausgelöst.
  • Verhalten bei sitzungsbasiertem Kanal: Eine Sitzung und ein InstanceContext pro Kanal.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Ein InstanceContext pro Aufruf.
  • Verhalten bei sitzungsbasiertem Kanal: Eine Ausnahme wird ausgelöst.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Ein InstanceContext pro Aufruf.

Single

  • Verhalten bei sitzungsbasiertem Kanal: Eine Sitzung und ein InstanceContext für alle Aufrufe.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Eine Ausnahme wird ausgelöst.
  • Verhalten bei sitzungsbasiertem Kanal: Eine Sitzung und ein InstanceContext für den erstellten bzw. den vom Benutzer angegebenen Singleton.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Ein InstanceContext für den erstellten bzw. den vom Benutzer angegebenen Singleton.
  • Verhalten bei sitzungsbasiertem Kanal: Eine Ausnahme wird ausgelöst.
  • Verhalten bei nicht sitzungsbasiertem Kanal: Ein InstanceContext für jeden erstellten Singleton oder für den vom Benutzer angegebenen Singleton.

Siehe auch

Aufgaben

Gewusst wie: Erstellen eines Diensts, der Sitzungen erfordert
Gewusst wie: Steuern der Dienstinstanzierung

Konzepte

Verwenden von Sitzungen

Weitere Ressourcen

Concurrency
Instancing
Service Contract: Session