Sessions, instanciation et accès concurrentiel

Une session est une corrélation de tous les messages envoyés entre deux points de terminaison. L'instanciation fait référence au contrôle de la durée de vie des objets de service définis par l'utilisateur et de leurs objets InstanceContext connexes. Laconcurrence est le terme donné au contrôle du nombre des threads qui s'exécutent simultanément dans un InstanceContext .

Cette rubrique décrit ces paramètres, comment les utiliser et les diverses interactions entre eux.

Sessions

Lorsqu'un contrat de service affecte ServiceContractAttribute.SessionMode à la propriété SessionMode.Required, ce contrat indique que tous les appels (c'est-à-dire, les échanges de messages sous-jacents qui prennent en charge les appels) doivent faire partie de la même conversation. Si un contrat spécifie qu'il autorise les sessions mais n'en requiert pas, les clients peuvent se connecter et établir ou non une session. Si la session se termine et qu'un message est envoyé sur le même canal basé sur session, une exception est levée.

Les sessions WCF sont associées aux principales fonctionnalités conceptuelles suivantes :

  • Elles sont explicitement initialisées et terminées par l'application appelante.

  • Les messages remis pendant une session sont traités dans l'ordre dans lequel ils sont reçus.

  • Les sessions corrèlent un groupe de messages dans une conversation. La signification de cette corrélation est une abstraction. Par exemple, un canal basé sur session peut corréler des messages sur la base d'une connexion réseau partagée, pendant qu'un autre canal basé sur session corrèle des messages sur la base d'une balise partagée dans le corps du message. Les fonctionnalités qui peuvent être dérivées de la session varient en fonction de la nature de la corrélation.

  • Il n’existe pas de magasin de données général associé à une session WCF.

Si vous connaissez la classe System.Web.SessionState.HttpSessionState des applications ASP.NET et les fonctionnalités qu’elle fournit, vous remarquerez les différences suivantes entre ce type de session et les sessions WCF :

  • Les sessions ASP.NET sont toujours lancées par le serveur.

  • Les sessions ASP.NET sont implicitement non ordonnées.

  • Les sessions ASP.NET fournissent un mécanisme de stockage général des données parmi l’ensemble des requêtes.

Les applications clientes et de service interagissent avec les sessions de manière différente. Les applications clientes initialisent des sessions, puis reçoivent et traitent les messages envoyés dans la session. Les applications de service peuvent utiliser des sessions comme point d'extensibilité pour ajouter un comportement supplémentaire. Pour ce faire, utilisez directement InstanceContext ou implémentez un fournisseur de contexte d'instance personnalisé.

Instanciation

Le comportement d'instanciation (défini à l'aide de propriété ServiceBehaviorAttribute.InstanceContextMode ) contrôle la façon dont le InstanceContext est créé en réponse à des messages entrants. Par défaut, chaque InstanceContext est associé à un objet de service défini par l'utilisateur ; par conséquent (dans le cas par défaut), la définition de la propriété InstanceContextMode contrôle également l'instanciation des objets de service définis par l'utilisateur. L'énumération InstanceContextMode définit les modes d'instanciation.

Les modes d'instanciation disponibles sont les suivants :

  • PerCall: un nouveau InstanceContext (et par conséquent un objet de service) est créé pour chaque demande du client.

  • PerSession: un nouveau InstanceContext (et par conséquent un objet de service) est créé pour chaque nouvelle session cliente et est conservé pendant toute la durée de vie de celle-ci (cela requiert une liaison capable de prendre les sessions en charge).

  • Single: un InstanceContext unique (et par conséquent un objet de service) gère toutes les demandes du client pendant toute la durée de vie de l'application.

L'exemple de code suivant présente la valeur InstanceContextMode par défaut, PerSession étant explicitement défini sur une classe de service.

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

Et pendant que la propriété ServiceBehaviorAttribute.InstanceContextMode contrôle la fréquence à laquelle InstanceContext est diffusé, les propriétés OperationBehaviorAttribute.ReleaseInstanceMode et ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete contrôlent le moment auquel l'objet de service est diffusé.

Services singleton connus

L'une des variantes des objets de service d'instance unique s'avère parfois utile : vous pouvez créer un objet de service vous-même, puis créer l'hôte de service à l'aide de cet objet. Pour ce faire, vous devez également affecter ServiceBehaviorAttribute.InstanceContextMode à la propriété Single , sans quoi une exception est levée lorsque l'hôte de service est ouvert.

Utilisez le constructeur ServiceHost(Object, Uri[]) pour créer un service de ce type. Il fournit une alternative à l'implémentation d'un System.ServiceModel.Dispatcher.IInstanceContextInitializer personnalisé lorsque vous souhaitez fournir une instance d'objet spécifique qui sera utilisée par un service singleton. Vous pouvez utiliser cette surcharge lorsque votre type d’implémentation de service est difficile à construire (par exemple, s’il n’implémente pas de constructeur public sans paramètre).

Notez que lorsqu’un objet est fourni à ce constructeur, certaines des fonctionnalités associées au comportement d’instanciation Windows Communication Foundation (WCF) fonctionnent différemment. Par exemple, l'appel de InstanceContext.ReleaseServiceInstance n'a aucun effet lorsqu'une instance d'objet singleton est fournie. De même, tout autre mécanisme de libération d'instance est ignoré. ServiceHost se comporte systématiquement comme si la propriété OperationBehaviorAttribute.ReleaseInstanceMode avait la valeur ReleaseInstanceMode.None pour toutes les opérations.

Partage d'objets InstanceContext

Vous pouvez également contrôler l'appel ou le canal de session associé à tel ou tel objet InstanceContext en effectuant vous-même l'association.

Accès concurrentiel

La concurrence est le contrôle du nombre de threads actifs simultanément dans un InstanceContext . Cela est contrôlé en utilisant ServiceBehaviorAttribute.ConcurrencyMode avec l'énumération ConcurrencyMode .

Les trois modes de concurrence disponibles sont les suivants :

  • Single: chaque contexte d'instance est autorisé à avoir au maximum un seul thread à la fois qui traite des messages dans le contexte d'instance. Les autres threads qui souhaitent utiliser le même contexte d'instance doivent se bloquer jusqu'à ce que le thread d'origine quitte le contexte d'instance.

  • Multiple: chaque instance de service peut avoir plusieurs threads qui traitent des messages simultanément. Pour utiliser ce mode, l'implémentation de service doit être « thread-safe ».

  • Reentrant: chaque instance de service traite un seul message à la fois, mais accepte les appels réentrants. Le service accepte uniquement ces appels lorsqu’il appelle via un objet client WCF .

Notes

Le fonctionnement et le développement de code utilisant plusieurs threads en toute sécurité peuvent s'avérer difficile à écrire. Avant d'utiliser les valeurs Multiple ou Reentrant , assurez-vous que votre service est correctement conçu pour ces modes. Pour plus d’informations, consultez ConcurrencyMode.

L'utilisation de l'accès concurrentiel est associée au mode d'instanciation. Dans l’instanciation PerCall, la concurrence n’est pas pertinente, car chaque message est traité par un nouvel objet InstanceContext et, par conséquent, il n’y a jamais plusieurs threads actifs dans l’objet InstanceContext.

L'exemple de code suivant présente l'affectation de ConcurrencyMode à la propriété Multiple.

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

Sessions interagissant avec les paramètres InstanceContext

Les sessions et InstanceContext interagissent en fonction de la combinaison de la valeur de l'énumération SessionMode dans un contrat et la propriété ServiceBehaviorAttribute.InstanceContextMode sur l'implémentation de service, qui contrôle l'association entre les canaux et des objets de service spécifiques.

Le tableau suivant présente le résultat d'un canal entrant prenant ou non en charge les sessions en fonction de la combinaison des valeurs de la propriété ServiceContractAttribute.SessionMode et de la propriété ServiceBehaviorAttribute.InstanceContextMode d'un service.

Valeur InstanceContextMode Required Allowed NotAllowed
PerCall - Comportement avec canal de session : une session et InstanceContext pour chaque appel.
- Comportement avec canal sans session : une exception est levée.
- Comportement avec canal de session : une session et InstanceContext pour chaque appel.
- Comportement avec canal sans session : InstanceContext pour chaque appel.
- Comportement avec canal de session : une exception est levée.
- Comportement avec canal sans session : InstanceContext pour chaque appel.
PerSession - Comportement avec canal de session : une session et InstanceContext pour chaque canal.
- Comportement avec canal sans session : une exception est levée.
- Comportement avec canal de session : une session et InstanceContext pour chaque canal.
- Comportement avec canal sans session : InstanceContext pour chaque appel.
- Comportement avec canal de session : une exception est levée.
- Comportement avec canal sans session : InstanceContext pour chaque appel.
Unique - Comportement avec canal de session : une session et un seul InstanceContext pour tous les appels.
- Comportement avec canal sans session : une exception est levée.
- Comportement avec canal de session : une session et InstanceContext pour le singleton créé ou spécifié par l’utilisateur.
- Comportement avec canal sans session : InstanceContext pour le singleton créé ou spécifié par l’utilisateur.
- Comportement avec canal de session : une exception est levée.
- Comportement avec canal sans session : InstanceContext pour chaque singleton créé ou le singleton spécifié par l’utilisateur.

Voir aussi