ServiceBehaviorAttribute.ConcurrencyMode Właściwość

Definicja

Pobiera lub ustawia, czy usługa obsługuje jeden wątek, wiele wątków, czy wywołania ponownego jednostki.

public:
 property System::ServiceModel::ConcurrencyMode ConcurrencyMode { System::ServiceModel::ConcurrencyMode get(); void set(System::ServiceModel::ConcurrencyMode value); };
public System.ServiceModel.ConcurrencyMode ConcurrencyMode { get; set; }
member this.ConcurrencyMode : System.ServiceModel.ConcurrencyMode with get, set
Public Property ConcurrencyMode As ConcurrencyMode

Wartość właściwości

ConcurrencyMode

ConcurrencyMode Jedną z wartości; wartość domyślna to Single.

Wyjątki

Wartość nie jest jedną z ConcurrencyMode wartości.

Przykłady

W poniższym przykładzie kodu pokazano różnice między użyciem metody Single, Reentranti Multiple. Ten przykład nie kompiluje się bez rzeczywistej implementacji, ale pokazuje rodzaj wątków gwarantuje, że Windows Communication Foundation (WCF) sprawia, że i co to oznacza dla kodu operacji.

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;
  }
}

Uwagi

Ta właściwość wskazuje, czy wystąpienie usługi może obsługiwać jeden wątek lub wiele wątków, które są wykonywane współbieżnie, a jeśli jednowątkowa, czy ponowne logowanie jest obsługiwane.

Uwaga

Właściwość ConcurrencyMode współdziała z innymi ustawieniami. Jeśli na przykład wartość jest ustawiona na Single wynik, usługa może przetwarzać tylko jeden komunikat w danym momencie, InstanceContextMode chyba że ustawiono ConcurrencyMode również wartość Multiplena . Ta właściwość tworzy również zachowanie w połączeniu z właściwością ServiceContractAttribute.SessionMode . Aby uzyskać szczegółowe informacje , zobacz Sesje, Instancing i Współbieżność.

Ustawienie ConcurrencyMode w celu Single poinstruowania systemu o ograniczeniu wystąpień usługi do jednego wątku wykonywania w danym momencie, co zwalnia Cię z rozwiązywania problemów z wątkami. Wartość oznacza Multiple , że obiekty usługi mogą być wykonywane przez wiele wątków w dowolnym momencie. W takim przypadku należy zapewnić bezpieczeństwo wątków.

Reentrant jednocześnie ogranicza dostęp do pojedynczego wątku; podczas przetwarzania operacji żaden inny komunikat nie może wprowadzić operacji. Jeśli podczas operacji zostanie wykonane wywołanie innej usługi, bieżący komunikat utraci blokadę operacji, która jest bezpłatna do przetwarzania innych komunikatów. Po powrocie wywołania usługi blokada zostanie ponownie wysłana, a oryginalny komunikat może kontynuować przetwarzanie do jego wniosku lub do momentu wystąpienia innego wywołania operacji.

Ważne

Mimo że Single ogranicza wystąpienia usługi do jednego wątku wykonywania w danym momencie, należy również ustawić MaxConcurrentCalls wartość 1, aby zagwarantować brak komunikatów poza kolejnością.

Ponadto odpowiedzialność za pozostawienie stanu obiektu jest spójne przed wywołaniami i należy potwierdzić, że dane operacji lokalnej są prawidłowe po wywołaniach. Należy pamiętać, że wystąpienie usługi jest odblokowane tylko przez wywołanie innej usługi za pośrednictwem kanału WCF. W takim przypadku wywołana usługa może ponownie wprowadzić pierwszą usługę za pośrednictwem wywołania zwrotnego. Jeśli pierwsza usługa nie jest ponownie włączona, sekwencja wywołań powoduje zakleszczenie. Aby uzyskać szczegółowe informacje, zobacz ConcurrencyMode.

Podczas dowolnego wywołania wychodzącego z operacji przetwarzania można modyfikować dane nie lokalne do operacji. (W przypadku wznowienia przetwarzania oryginalnego komunikatu dane stanu lokalnego są prawidłowe). W związku z tym przed wywołaniem wychodzącym należy upewnić się, że dane inne niż lokalne są prawidłowe dla innych połączeń przychodzących i ponownie zrealiduj dane inne niż lokalne po powrocie wywołania wychodzącego.

Poniższy pseudo-kod ilustruje wymagany wzorzec dla pomyślnej obsługi ponownego cyklu.

public void MyMethod()  
{  
  this.SomeNonLocalDataState;  
  // Here you need to clean nonlocal state for other users  
  OutboundProxy proxy = new OutboundProxy();  
  int returnValue = proxy.CallOutOfOperation();  
  // Ensure that this.SomeNonLocalDataState is valid for continued use.  
  this.ModifyNonLocalState;  
  return returnValue;  
}  

Użyj wzorca wywołania asynchronicznego Begin/End dla wywołania wychodzącego, gdy ConcurrencyMode element wyzwala Reentrant wyjątek. Asynchroniczne wywołania ruchu wychodzącego wymagają operacji, w której ConcurrencyMode jest Multiple, w tym przypadku należy obsługiwać problemy z synchronizacją.

Ogólnie rzecz biorąc, jeśli zostanie wyświetlony komunikat dla wystąpienia, które narusza tryb współbieżności, komunikat czeka na udostępnienie wystąpienia lub do momentu jego limitu czasu.

Ponadto jeśli ConcurrencyMode parametr jest ustawiony na Single , a wywołanie ponownego jednostki jest blokowane podczas oczekiwania na zwolnienie wystąpienia, system wykrywa zakleszczenie i zgłasza wyjątek.

Uwaga

Element InvalidOperationException jest zgłaszany w czasie wykonywania, jeśli ReleaseServiceInstanceOnTransactionComplete true właściwość jest ustawiona ConcurrencyMode na Singlewartość .

Należy pamiętać, że należy jawnie ustawić ReleaseServiceInstanceOnTransactionComplete false wartość , jeśli istnieje operacja z ustawioną wartością OperationBehaviorAttribute.TransactionScopeRequired true i ustawiono wartość ConcurrencyMode Reentrant. W przeciwnym razie zgłaszany jest wyjątek weryfikacji, ponieważ wartość domyślna ReleaseServiceInstanceOnTransactionComplete to true.

Istnieje interakcja ConcurrencyMode z innymi właściwościami, które mogą zmieniać zachowanie środowiska uruchomieniowego. Pełny opis tych interakcji można znaleźć w temacie Sesje, Instancing i Współbieżność.

Dotyczy