ConcurrencyMode Enumerazione
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Specifica se una classe di servizio supporta le modalità a thread singolo o multithreading dell'operazione.
public enum class ConcurrencyMode
public enum ConcurrencyMode
type ConcurrencyMode =
Public Enum ConcurrencyMode
- Ereditarietà
Campi
| Nome | Valore | Descrizione |
|---|---|---|
| Single | 0 | L'istanza del servizio è a thread singolo e non accetta chiamate rientranti. Se la InstanceContextMode proprietà è Singlee arrivano messaggi aggiuntivi mentre l'istanza esegue una chiamata, questi messaggi devono attendere fino a quando il servizio non è disponibile o fino al timeout dei messaggi. |
| Reentrant | 1 | L'istanza del servizio è a thread singolo e accetta chiamate reentranti. Il servizio reentrant accetta chiamate quando si chiama un altro servizio; è pertanto responsabilità dell'utente lasciare coerente lo stato dell'oggetto prima dei callout ed è necessario verificare che i dati locali dell'operazione siano validi dopo i callout. Si noti che l'istanza del servizio viene sbloccata solo chiamando un altro servizio su un canale WCF. In questo caso, il servizio chiamato può reinserire il primo servizio tramite un callback. Se il primo servizio non è reentrant, la sequenza di chiamate genera un deadlock. Per informazioni dettagliate, vedere ConcurrencyMode. |
| Multiple | 2 | L'istanza del servizio è multithread. Non vengono effettuate garanzie di sincronizzazione. Poiché altri thread possono modificare l'oggetto servizio in qualsiasi momento, è necessario gestire sempre la sincronizzazione e la coerenza dello stato. |
Esempio
L'esempio di codice seguente illustra le differenze tra l'uso di Single, Reentrant e Multiple. Questo esempio non viene compilato senza un'implementazione reale, ma illustra il tipo di threading garantito da WCF e ciò che significa per il codice dell'operazione.
using System;
using System.ServiceModel;
[ServiceContract]
public interface IHttpFetcher
{
[OperationContract]
string GetWebPage(string address);
}
// These classes have the invariant that:
// this.slow.GetWebPage(this.cachedAddress) == this.cachedWebPage.
// When you read cached values you can assume they are valid. When
// you write the cached values, you must guarantee that they are valid.
// With ConcurrencyMode.Single, WCF does not call again into the object
// so long as the method is running. After the operation returns the object
// can be called again, so you must make sure state is consistent before
// returning.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
class SingleCachingHttpFetcher : IHttpFetcher
{
string cachedWebPage;
string cachedAddress;
readonly IHttpFetcher slow;
public string GetWebPage(string address)
{
// <-- Can assume cache is valid.
if (this.cachedAddress == address)
{
return this.cachedWebPage;
}
// <-- Cache is no longer valid because we are changing
// one of the values.
this.cachedAddress = address;
string webPage = slow.GetWebPage(address);
this.cachedWebPage = webPage;
// <-- Cache is valid again here.
return this.cachedWebPage;
// <-- Must guarantee that the cache is valid because we are returning.
}
}
// With ConcurrencyMode.Reentrant, WCF makes sure that only one
// thread runs in your code at a time. However, when you call out on a
// channel, the operation can get called again on another thread. Therefore
// you must confirm that state is consistent both before channel calls and
// before you return.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class ReentrantCachingHttpFetcher : IHttpFetcher
{
string cachedWebPage;
string cachedAddress;
readonly SlowHttpFetcher slow;
public ReentrantCachingHttpFetcher()
{
this.slow = new SlowHttpFetcher();
}
public string GetWebPage(string address)
{
// <-- Can assume that cache is valid.
if (this.cachedAddress == address)
{
return this.cachedWebPage;
}
// <-- Must guarantee that the cache is valid, because
// the operation can be called again before we return.
string webPage = slow.GetWebPage(address);
// <-- Can assume cache is valid.
// <-- Cache is no longer valid because we are changing
// one of the values.
this.cachedAddress = address;
this.cachedWebPage = webPage;
// <-- Cache is valid again here.
return this.cachedWebPage;
// <-- Must guarantee that cache is valid because we are returning.
}
}
// With ConcurrencyMode.Multiple, threads can call an operation at any time.
// It is your responsibility to guard your state with locks. If
// you always guarantee you leave state consistent when you leave
// the lock, you can assume it is valid when you enter the lock.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
class MultipleCachingHttpFetcher : IHttpFetcher
{
string cachedWebPage;
string cachedAddress;
readonly SlowHttpFetcher slow;
readonly object ThisLock = new object();
public MultipleCachingHttpFetcher()
{
this.slow = new SlowHttpFetcher();
}
public string GetWebPage(string address)
{
lock (this.ThisLock)
{
// <-- Can assume cache is valid.
if (this.cachedAddress == address)
{
return this.cachedWebPage;
// <-- Must guarantee that cache is valid because
// the operation returns and releases the lock.
}
// <-- Must guarantee that cache is valid here because
// the operation releases the lock.
}
string webPage = slow.GetWebPage(address);
lock (this.ThisLock)
{
// <-- Can assume cache is valid.
// <-- Cache is no longer valid because the operation
// changes one of the values.
this.cachedAddress = address;
this.cachedWebPage = webPage;
// <-- Cache is valid again here.
// <-- Must guarantee that cache is valid because
// the operation releases the lock.
}
return webPage;
}
}
Commenti
ConcurrencyMode viene utilizzato insieme alla ConcurrencyMode proprietà per specificare se una classe di servizio supporta le modalità a thread singolo o multithreading dell'operazione. Un'operazione a thread singolo può essere reentrant o non reentrant.
Nella tabella seguente viene illustrato quando Windows Communication Foundation (WCF) consente di richiamare un'operazione mentre è in corso un'altra operazione, a seconda di ConcurrencyMode.
| Valore concurrencyMode | È possibile richiamare una nuova operazione? |
|---|---|
| Single | Mai. |
| Rientrante | Solo quando si richiama un altro servizio o un callback. |
| Multiple | Sempre. |