Sessioni, istanze e concorrenza

Una sessione è una correlazione di tutti i messaggi inviati tra due endpoint. La creazione di istanze fa riferimento al controllo della durata di oggetti servizio definiti dall'utente e di oggetti InstanceContext correlati. La concorrenza è il termine dato al controllo del numero di thread in esecuzione contemporaneamente in un InstanceContext.

In questo argomento vengono descritte tali impostazioni, come utilizzarle e le varie interazioni tra di esse.

Sessioni

Quando la proprietà System.ServiceModel.ServiceContractAttribute.SessionMode viene impostata da un contratto di servizio su System.ServiceModel.SessionMode.Required, tutte le chiamate, ovvero gli scambi di messaggi sottostanti che supportano le chiamate, devono essere parte della stessa conversazione. Se un contratto consente sessioni ma non ne richiede, i client possono connettersi e possono stabilire o meno una sessione. Se, al termine della sessione, un messaggio viene inviato sullo stesso canale basato sulla sessione, viene generata un'eccezione.

Le principali caratteristiche delle sessioni WCF sono le seguenti:

  • Vengono avviate e terminate esplicitamente dall'applicazione chiamante.
  • I messaggi recapitati durante una sessione vengono elaborati nell'ordine in cui vengono ricevuti.
  • Le sessioni consentono di correlare un gruppo di messaggi in una conversazione. Il significato di tale correlazione è un'astrazione. Un canale basato sulla sessione, ad esempio, è in grado di correlare messaggi basati su una connessione di rete condivisa mentre un altro canale basato sulla sessione è in grado di correlare messaggi basati su un tag condiviso nel corpo del messaggio. Le funzionalità che possono derivare dalla sessione dipendono dalla natura della correlazione.
  • Non esiste alcun archivio dati generale associato a una sessione WCF.

Se si ha familiarità con la classe System.Web.SessionState.HttpSessionState in applicazioni ASP.NET e con la funzionalità fornita, è possibile notare le differenze seguenti tra quel tipo di sessioni e le sessioni WCF:

  • Le sessioni ASP.NET sono sempre avviate dal server.
  • Le sessioni ASP.NET sono implicitamente non ordinate.
  • Le sessioni ASP.NET forniscono un meccanismo di archiviazione dati generale tramite richieste.

Le applicazioni client e le applicazioni di servizio interagiscono con le sessioni in modi diversi. Le applicazioni client avviano sessioni e quindi ricevono ed elaborano i messaggi inviati all'interno della sessione. Le applicazioni di servizio possono utilizzare le sessioni come punto di estendibilità per aggiungere comportamenti. Ciò si ottiene utilizzando direttamente InstanceContext o implementando un provider di contesto dell'istanza personalizzato.

Istanze

Il comportamento delle istanze (impostato tramite la proprietà System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode ) consente di controllare come viene creato InstanceContext in risposta ai messaggi in ingresso. Per impostazione predefinita, ogni InstanceContext viene associato a uno oggetto servizio definito dall'utente. In questo modo l'impostazione (nel caso predefinito) della proprietà InstanceContextMode consente di controllare anche le istanze di oggetti servizio definiti dall'utente. L'enumerazione InstanceContextMode definisce le modalità di istanza.

Sono disponibili le modalità di istanza seguenti:

  • PerCall: viene creato un nuovo InstanceContext (e di conseguenza l'oggetto servizio) per ogni richiesta client.
  • PerSession: viene creato un nuovo InstanceContext (e di conseguenza l'oggetto servizio) per ogni sessione client nuova e viene mantenuto per la durata di quella sessione (è necessaria un'associazione che supporti sessioni).
  • Single: un unico InstanceContext (e di conseguenza l'oggetto servizio) gestisce tutte le richieste client per la durata dell'applicazione.

Nell'esempio di codice seguente viene illustrato il valore InstanceContextMode predefinito, con PerSession impostato esplicitamente su una classe del servizio.

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

Mentre la proprietà System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode consente di controllare la frequenza di rilascio di InstanceContext, le proprietà System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode e System.ServiceModel.ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete consentono di controllare quando l'oggetto servizio viene rilasciato.

Servizi Singleton noti

Una variazione su oggetti servizio di una singola istanza può a volte essere utile. È infatti possibile creare un oggetto servizio e quindi creare l'host del servizio tramite quell'oggetto. A tale scopo, è necessario impostare la proprietà System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode su Single, in caso contrario verrà generata un'eccezione quando l'host del servizio viene aperto.

Utilizzare il costruttore System.ServiceModel.ServiceHost.#ctor(System.Object,System.Uri[]) per creare tale servizio. Fornisce un'alternativa all'implementazione di un'interfaccia System.ServiceModel.Dispatcher.IInstanceContextInitializer personalizzata quando si desidera fornire un'istanza specifica dell'oggetto utilizzabile da un servizio singleton. Questo overload può risultare utile quando il tipo di implementazione del servizio è di difficile costruzione, ad esempio se non implementa alcun costruttore pubblico predefinito privo di parametri.

Si noti che quando un oggetto viene fornito a questo costruttore, alcune funzionalità relative al comportamento di creazione delle istanze Windows Communication Foundation (WCF) operano in modo diverso. La chiamata, ad esempio, di System.ServiceModel.InstanceContext.ReleaseServiceInstance non ha effetto quando viene fornita l'istanza di un oggetto Singleton. Analogamente, qualsiasi altro meccanismo di rilascio delle istanze viene ignorato. L'host ServiceHost si comporta sempre come se la proprietà System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode fosse impostata su System.ServiceModel.ReleaseInstanceMode.None per tutte le operazioni.

Condivisione di oggetti InstanceContext

È inoltre possibile controllare l'associazione tra canali o chiamate con sessione e oggetti InstanceContext eseguendo quell'associazione. Per un esempio completo, vedere InstanceContextSharing.

Concorrenza

La concorrenza è il controllo del numero di thread attivi in un InstanceContext contemporaneamente. Viene controllato tramite System.ServiceModel.ServiceBehaviorAttribute.ConcurrencyMode con l'enumerazione ConcurrencyMode.

Sono disponibili le tre modalità di concorrenza seguenti:

  • Single: ogni contesto dell'istanza può avere al massimo un thread alla volta per l'elaborazione dei messaggi nel contesto dell'istanza. Altri thread che devono utilizzare lo stesso contesto dell'istanza, devono restare bloccati fino alla chiusura del thread originale dal contesto dell'istanza.
  • Multiple: ogni istanza del servizio può avere contemporaneamente più thread per l'elaborazione messaggi. Per essere in grado di utilizzare questa modalità di concorrenza, l'implementazione del servizio deve essere thread-safe.
  • Reentrant: ogni istanza del servizio elabora un messaggio alla volta ma accetta chiamate di operazioni rientranti. Il servizio accetta queste chiamate solo quando è in corso una chiamata in uscita tramite un oggetto client WCF.

Nota

Può essere difficile comprendere, scrivere correttamente e sviluppare codice che utilizza in modo sicuro più di un thread. Prima di utilizzare valori Multiple o Reentrant, verificare che il servizio sia progettato correttamente per queste modalità. Per ulteriori informazioni, vedere ConcurrencyMode.

L'utilizzo della concorrenza è correlato alla modalità di istanza. Nelle istanze PerCall la concorrenza non è rilevante, poiché ogni messaggio viene elaborato da un nuovo InstanceContext e, pertanto, non è mai attivo più di un singolo thread in InstanceContext.

Nell'esempio di codice seguente viene illustrata l'impostazione della proprietà ConcurrencyMode su Multiple.

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

Sessioni che interagiscono con impostazioni InstanceContext

L'interazione di sessioni e di InstanceContext, che dipendono dalla combinazione tra il valore dell'enumerazione SessionMode in un contratto e la proprietà System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode nell'implementazione del servizio, consente di controllare l'associazione tra canali e oggetti servizio specifici.

Nella tabella seguente viene mostrato il risultato di un canale in ingresso in cui le sessioni sono supportate o non supportate. Tale risultato è in funzione della combinazione dei valori delle proprietà System.ServiceModel.ServiceContractAttribute.SessionMode e System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode del servizio.

Valore InstanceContextMode Required Allowed NotAllowed

PerCall

  • Comportamento in caso di canale con sessione: una sessione e un contesto InstanceContext per ogni chiamata.
  • Comportamento in caso di canale senza sessione: viene generata un'eccezione.
  • Comportamento in caso di canale con sessione: una sessione e un contesto InstanceContext per ogni chiamata.
  • Comportamento in caso di canale senza sessione: un contesto InstanceContext per ogni chiamata.
  • Comportamento in caso di canale con sessione: viene generata un'eccezione.
  • Comportamento in caso di canale senza sessione: un contesto InstanceContext per ogni chiamata.

PerSession

  • Comportamento in caso di canale con sessione: una sessione e un contesto InstanceContext per ogni canale.
  • Comportamento in caso di canale senza sessione: viene generata un'eccezione.
  • Comportamento in caso di canale con sessione: una sessione e un contesto InstanceContext per ogni canale.
  • Comportamento in caso di canale senza sessione: un contesto InstanceContext per ogni chiamata.
  • Comportamento in caso di canale con sessione: viene generata un'eccezione.
  • Comportamento in caso di canale senza sessione: un contesto InstanceContext per ogni chiamata.

Single

  • Comportamento in caso di canale con sessione: un'unica sessione e un solo InstanceContext per tutte le chiamate.
  • Comportamento in caso di canale senza sessione: viene generata un'eccezione.
  • Comportamento in caso di canale con sessione: una sessione e un InstanceContext per il singleton creato o per il singleton specificato dall'utente.
  • Comportamento in caso di canale senza sessione: un InstanceContext per il singleton creato o per il singleton specificato dall'utente.
  • Comportamento in caso di canale con sessione: viene generata un'eccezione.
  • Comportamento in caso di canale senza sessione: un contesto InstanceContext per ogni singleton creato o per il singleton specificato dall'utente.

Vedere anche

Attività

Procedura: creare un servizio che richiede sessioni
Procedura: controllare l'istanza del servizio

Concetti

Utilizzo di sessioni

Altre risorse

Concurrency
Instancing
Service Contract: Session