ConcurrencyMode Enum

Definition

Anger om en tjänstklass stöder entrådade eller flertrådade driftlägen.

public enum class ConcurrencyMode
public enum ConcurrencyMode
type ConcurrencyMode = 
Public Enum ConcurrencyMode
Arv
ConcurrencyMode

Fält

Name Värde Description
Single 0

Tjänstinstansen är enkeltrådad och accepterar inte återaktiveringsanrop. Om egenskapen InstanceContextMode är Single, och ytterligare meddelanden tas emot medan instansen servar ett anrop, måste dessa meddelanden vänta tills tjänsten är tillgänglig eller tills tidsgränsen för meddelandena överskrids.

Reentrant 1

Tjänstinstansen är enkeltrådad och accepterar återaktiveringsanrop. Tjänsten reentrant accepterar samtal när du anropar en annan tjänst. Det är därför ditt ansvar att lämna objekttillståndet konsekvent före pratbubblan och du måste bekräfta att åtgärdslokala data är giltiga efter pratbubblan. Observera att tjänstinstansen endast låss upp genom att anropa en annan tjänst via en WCF-kanal. I det här fallet kan den anropade tjänsten skicka den första tjänsten igen via ett återanrop. Om den första tjänsten inte är reentrant resulterar anropssekvensen i ett dödläge. Mer information finns i ConcurrencyMode.

Multiple 2

Tjänstinstansen är flera trådar. Inga synkroniseringsgarantier görs. Eftersom andra trådar kan ändra tjänstobjektet när som helst måste du alltid hantera synkronisering och tillståndskonsekvens.

Exempel

I följande kodexempel visas skillnaden mellan att använda Single, Reentrant och Multiple. Det här exemplet kompileras inte utan en verklig implementering bakom det, men visar den typ av trådningsgarantier som WCF gör och vad det innebär för din åtgärdskod.

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

Kommentarer

ConcurrencyMode används tillsammans med ConcurrencyMode egenskapen för att ange om en tjänstklass stöder entrådade eller flertrådade driftlägen. En enkeltrådad åtgärd kan vara antingen reentrant eller icke-reentrant.

Följande tabell visar när Windows Communication Foundation (WCF) tillåter att en åtgärd anropas medan en annan pågår, beroende på ConcurrencyMode.

ConcurrencyMode-värde Kan en ny åtgärd anropas?
Single Aldrig.
Reentrant Endast när du anropar en annan tjänst eller ett återanrop.
Flera Alltid.

Gäller för