ServiceBehaviorAttribute.ConcurrencyMode Eigenschap

Definitie

Hiermee wordt opgehaald of ingesteld of een service één thread, meerdere threads of nieuwe aanroepen ondersteunt.

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

Waarde van eigenschap

Een van de ConcurrencyMode waarden; de standaardwaarde is Single.

Uitzonderingen

De waarde is geen van de ConcurrencyMode waarden.

Voorbeelden

In het volgende codevoorbeeld ziet u de verschillen tussen het gebruik Single, Reentranten Multiple. Dit voorbeeld wordt niet gecompileerd zonder een echte implementatie erachter, maar demonstreert wel het soort threading dat Windows Communication Foundation (WCF) maakt en wat dat betekent voor uw bewerkingscode.

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

Opmerkingen

Deze eigenschap geeft aan of een exemplaar van een service één thread of meerdere threads kan verwerken die gelijktijdig worden uitgevoerd en of één thread wordt ondersteund, of reentrancy wordt ondersteund.

Note

De ConcurrencyMode eigenschap communiceert met enkele andere instellingen. Als de InstanceContextMode waarde bijvoorbeeld is ingesteld op Single het resultaat, is dat uw service slechts één bericht tegelijk kan verwerken, tenzij u ook de ConcurrencyMode waarde instelt op Multiple. Deze eigenschap produceert ook gedrag in combinatie met de ServiceContractAttribute.SessionMode eigenschap. Zie Sessies, Instancing en Gelijktijdigheid voor meer informatie.

Instelling ConcurrencyMode voor Single het instrueren van het systeem om exemplaren van de service te beperken tot één thread van uitvoering tegelijk, waardoor u geen threadingproblemen kunt oplossen. Een waarde van Multiple dit type betekent dat serviceobjecten op elk gewenst moment door meerdere threads kunnen worden uitgevoerd. In dit geval moet u de veiligheid van threads garanderen.

Reentrant beperkt ook de toegang tot één thread tegelijk; terwijl de bewerking wordt verwerkt, kan er geen ander bericht de bewerking invoeren. Als tijdens de bewerking een aanroep naar een andere service vertrekt, verliest het huidige bericht de vergrendeling van de bewerking, wat gratis is om andere berichten te verwerken. Wanneer de service wordt teruggeroepen, wordt de vergrendeling hersteld en kan het oorspronkelijke bericht blijven verwerken tot de conclusie of totdat een andere aanroep van de bewerking optreedt.

Important

Single Hoewel exemplaren van de service worden beperkt tot één thread van uitvoering tegelijk, moet u ook 1 instellen MaxConcurrentCalls om geen berichten buiten de volgorde te garanderen.

Het is ook uw verantwoordelijkheid om uw objectstatus consistent te laten voordat bijschriften worden weergegeven en u moet bevestigen dat de lokale gegevens van de bewerking geldig zijn na bijschriften. Houd er rekening mee dat het service-exemplaar alleen is ontgrendeld door een andere service aan te roepen via een WCF-kanaal. In dit geval kan de aangeroepen service de eerste service opnieuw uitvoeren via een callback. Als de eerste service niet opnieuw wordt gebruikt, resulteert de reeks aanroepen in een impasse. Zie ConcurrencyModevoor meer informatie.

Tijdens een uitgaande oproep vanuit een verwerkingsbewerking kunnen gegevens die niet lokaal zijn voor de bewerking, worden gewijzigd. (Lokale statusgegevens zijn gegarandeerd geldig wanneer het oorspronkelijke bericht wordt verwerkt.) Als gevolg hiervan moet u vóór uw uitgaande oproep ervoor zorgen dat niet-lokale gegevens geldig zijn voor andere binnenkomende oproepen en niet-lokale gegevens opnieuw valideren nadat de uitgaande oproep is geretourneerd.

De volgende pseudocode illustreert het vereiste patroon voor succesvolle reentrant-ondersteuning.

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

Gebruik het asynchrone aanroeppatroon Begin/End voor een uitgaande aanroep wanneer een ConcurrencyMode uitzondering wordt Reentrant geactiveerd. Voor asynchrone uitgaande aanroepen is een bewerking vereist. ConcurrencyModeMultipleIn dat geval moet u synchronisatieproblemen afhandelen.

Als een bericht binnenkomt voor een exemplaar dat de gelijktijdigheidsmodus schendt, wacht het bericht totdat het beschikbaar is of tot er een time-out optreedt.

Bovendien, als de ConcurrencyMode is ingesteld Single op en een reentrant-aanroep wordt geblokkeerd terwijl wordt gewacht tot het exemplaar wordt vrijgemaakt, detecteert het systeem de impasse en genereert een uitzondering.

Note

Een InvalidOperationException wordt tijdens runtime gegenereerd als ReleaseServiceInstanceOnTransactionCompletetrue de ConcurrencyMode eigenschap is ingesteld op Single.

Houd er rekening mee dat u expliciet moet instellen ReleaseServiceInstanceOnTransactionCompletefalse op als er een bewerking is die OperationBehaviorAttribute.TransactionScopeRequired is ingesteld op true en u instelt ConcurrencyMode op Reentrant. Anders wordt er een validatie-uitzondering gegenereerd omdat de standaardwaarde ReleaseServiceInstanceOnTransactionComplete is true.

Er is een interactie van de ConcurrencyMode en andere eigenschappen die het runtimegedrag kunnen wijzigen. Zie Sessies, Instancing en Gelijktijdigheid voor een volledige beschrijving van deze interacties.

Van toepassing op