ConcurrencyMode Enumeração
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Especifica se uma classe de serviço suporta modos de operação single-threaded ou multi-threaded.
public enum class ConcurrencyMode
public enum ConcurrencyMode
type ConcurrencyMode =
Public Enum ConcurrencyMode
- Herança
Campos
| Name | Valor | Description |
|---|---|---|
| Single | 0 | A instância de serviço é single-threaded e não aceita chamadas de reentrante. Se a InstanceContextMode propriedade for Single, e chegarem mensagens adicionais enquanto a instância serve uma chamada, estas mensagens devem esperar até que o serviço esteja disponível ou até que as mensagens expirem. |
| Reentrant | 1 | A instância de serviço é single-threaded e aceita chamadas de reentrante. O serviço de reentrada aceita chamadas quando se liga para outro serviço; É, portanto, sua responsabilidade manter o estado do objeto consistente antes das chamadas e deve confirmar que os dados locais de operação são válidos após as chamadas (callouts). Note que a instância do serviço só é desbloqueada ao chamar outro serviço através de um canal WCF. Neste caso, o serviço chamado pode reintroduzir o primeiro serviço através de um callback. Se o primeiro serviço não for reentrante, a sequência de chamadas resulta num deadlock. Para obter detalhes, consulte ConcurrencyMode. |
| Multiple | 2 | A instância de serviço é multithread. Não são dadas garantias de sincronização. Como outros threads podem alterar o seu objeto de serviço a qualquer momento, deve gerir a sincronização e a consistência de estado em todos os momentos. |
Exemplos
O exemplo de código seguinte demonstra a diferença entre usar Single, Reentrant e Multiple. Este exemplo não compila sem uma implementação real por trás, mas demonstra o tipo de garantias de threading que o WCF oferece e o que isso significa para o seu código de operação.
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;
}
}
Observações
ConcurrencyMode é usado em conjunto com a ConcurrencyMode propriedade para especificar se uma classe de serviço suporta modos de operação single-threaded ou multi-threaded. Uma operação de thread única pode ser reentrante ou não reentrante.
A tabela seguinte mostra quando Windows Communication Foundation (WCF) permite que uma operação seja invocada enquanto outra está em curso, dependendo do ConcurrencyMode.
| Valor do Modo Concorrência | Pode ser invocada uma nova operação? |
|---|---|
| Single | Nunca. |
| Reentrante | Só ao invocar outro serviço ou um callback. |
| Vários | Sempre. |