ConcurrencyMode Wyliczenie

Definicja

Określa, czy klasa usługi obsługuje tryby jednowątkowa lub wielowątkowa operacji.

C#
public enum ConcurrencyMode
Dziedziczenie
ConcurrencyMode

Pola

Multiple 2

Wystąpienie usługi jest wielowątkowa. Nie są dokonywane żadne gwarancje synchronizacji. Ponieważ inne wątki mogą zmieniać obiekt usługi w dowolnym momencie, musisz obsługiwać synchronizację i spójność stanu przez cały czas.

Reentrant 1

Wystąpienie usługi jest jednowątkowa i akceptuje wywołania ponownego jednostki. Usługa reentrant akceptuje wywołania podczas wywoływania innej usługi; W związku z tym użytkownik ponosi odpowiedzialność za pozostawienie spójności stanu obiektu przed objaśnień i należy potwierdzić, że dane operacyjne-lokalne są prawidłowe po objaśnieniu. 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 ponowna, sekwencja wywołań powoduje zakleszczenie. Aby uzyskać szczegółowe informacje, zobacz ConcurrencyMode.

Single 0

Wystąpienie usługi jest jednowątkowa i nie akceptuje wywołań reentrant. InstanceContextMode Jeśli właściwość ma Singlewartość , a dodatkowe komunikaty docierają podczas wywołania usług wystąpień, te komunikaty muszą czekać, aż usługa będzie dostępna lub do momentu przekroczenia limitu czasu komunikatów.

Przykłady

W poniższym przykładzie kodu pokazano różnice między używaniem pojedynczych, ponownych wystąpień i wielokrotnych. Ten przykład nie jest kompilowany bez rzeczywistej implementacji, ale demonstruje rodzaj gwarancji wątków, które program WCF tworzy i co oznacza dla kodu operacji.

C#
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

ConcurrencyMode Parametr jest używany w połączeniu z właściwością ConcurrencyMode w celu określenia, czy klasa usługi obsługuje tryby jednowątkowe, czy wielowątkowy operacji. Jednowątkowa operacja może być jedną operacją reentrant lub nieodpartą.

W poniższej tabeli przedstawiono, kiedy Windows Communication Foundation (WCF) zezwala na wywoływanie operacji, gdy inna jest w toku, w zależności od ConcurrencyMode.

Wartość concurrencyMode Czy można wywołać nową operację?
Pojedynczy Nigdy nie.
Współużytkowane Tylko podczas wywoływania innej usługi lub wywołania zwrotnego.
Wiele Zawsze.

Dotyczy

Produkt Wersje
.NET Framework 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8