ServiceBehaviorAttribute.ConcurrencyMode Özellik

Tanım

Bir hizmetin bir iş parçacığını, birden çok iş parçacığını veya yeniden giriş çağrılarını destekleyip desteklemediğini alır veya ayarlar.

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

Özellik Değeri

Değerlerden ConcurrencyMode biri; varsayılan değerdir Single.

Özel durumlar

Değer değerlerden ConcurrencyMode biri değildir.

Örnekler

Aşağıdaki kod örneği, ve ReentrantMultiplekullanma Singlearasındaki farkı gösterir. Bu örnek arkasında gerçek bir uygulama olmadan derlenmez, ancak Windows Communication Foundation'ın (WCF) yaptığı iş parçacığı oluşturma garantilerinin türünü ve bunun işlem kodunuz için ne anlama geldiğini gösterir.

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

Açıklamalar

Bu özellik, bir hizmet örneğinin eşzamanlı olarak yürütülen bir iş parçacığını mı yoksa birden çok iş parçacığını mı işleyebileceğini ve tek iş parçacıklıysa yeniden giriş desteklenip desteklenmediğini gösterir.

Not

ConcurrencyMode özelliği diğer bazı ayarlarla etkileşim kurar. Örneğin, değer sonuca ayarlanırsaInstanceContextMode, değeri olarak ayarlamadığınız sürece hizmetinizin bir kerede yalnızca bir iletiyi işleyebileceğidirMultipleConcurrencyMode.Single Bu özellik ayrıca özelliğiyle ServiceContractAttribute.SessionMode birlikte davranış üretir. Ayrıntılar için bkz . Oturumlar, Tutarsızlık ve Eşzamanlılık.

ayarı ConcurrencyModeSingle , sisteme hizmet örneklerini bir kerede bir yürütme iş parçacığıyla kısıtlama yönergesi ve bu da iş parçacığı sorunlarıyla ilgilenmenizi engeller. değeri Multiple , hizmet nesnelerinin herhangi bir anda birden çok iş parçacığı tarafından yürütülebileceği anlamına gelir. Bu durumda, iş parçacığı güvenliğini sağlamanız gerekir.

Reentrant aynı anda tek bir iş parçacığına erişimi de kısıtlar; işlem işlenirken, başka hiçbir ileti işlemi giremez. İşlem sırasında başka bir hizmete yapılan bir çağrı ayrılırsa, geçerli ileti işlemdeki kilidi kaybeder ve bu da diğer iletileri işlemekte serbesttir. Hizmet çağrısı döndürdüğünde kilit yeniden oluşturulur ve özgün ileti, işlemin sonucuna kadar veya işlem dışında başka bir çağrı gerçekleşene kadar işlemeye devam edebilir.

Önemli

Hizmet örneklerini bir kerede bir yürütme iş parçacığıyla kısıtlasa Single da, sıra dışı ileti olmamasını garanti etmek için 1 olarak da ayarlamanız MaxConcurrentCalls gerekir.

Ayrıca, açıklama balonlarından önce nesne durumunuzu tutarlı bırakmak sizin sorumluluğunuzdadır ve işlem yerel verilerinin açıklama balonlarından sonra geçerli olduğunu onaylamanız gerekir. Hizmet örneğinin kilidinin yalnızca bir WCF kanalı üzerinden başka bir hizmet çağrılarak açıldığını unutmayın. Bu durumda, çağrılan hizmet bir geri arama yoluyla ilk hizmeti yeniden ekleyebilir. İlk hizmet yeniden oturum açmazsa, çağrı dizisi kilitlenmeyle sonuçlanır. Ayrıntılar için bkz. ConcurrencyMode.

bir işleme işleminden herhangi bir giden çağrı sırasında, işlemeye yerel olmayan veriler değiştirilebilir. (Özgün ileti işlemeye devam ettiğinde yerel durum verilerinin geçerli olacağı garanti edilir.) Sonuç olarak, giden aramanızdan önce yerel olmayan verilerin diğer gelen çağrılar için geçerli olduğundan emin olmanız ve giden arama geri döndükten sonra yerel olmayan verileri yeniden doğrulamanız gerekir.

Aşağıdaki sahte kod, başarılı yeniden oturum açma desteği için gerekli düzeni gösterir.

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

bir özel durum tetiklediğinde giden bir çağrı için Başlangıç/Bitiş zaman uyumsuz çağrı desenini ConcurrencyModeReentrant kullanma. Zaman uyumsuz giden çağrılar, içinde ConcurrencyModeMultipleolduğu bir işlem gerektirir. Bu durumda eşitleme sorunlarını işlemeniz gerekir.

Genellikle, eşzamanlılık modunu ihlal eden bir örnek için bir ileti gelirse, ileti örnek kullanılabilir olana kadar veya zaman aşımına uğramadan bekler.

Buna ek olarak, olarak ayarlanırsa Single ve örneğin serbest bırakılması beklenirken yeniden giriş çağrısı engellenirse ConcurrencyMode sistem kilitlenmeyi algılar ve bir özel durum oluşturur.

Not

InvalidOperationException özelliği olarak ayarlandığında Singleçalışma zamanında ReleaseServiceInstanceOnTransactionCompletetrueConcurrencyMode bir oluşturulur.

true olarak ayarlanmış ve olarak ayarlanmış ReleaseServiceInstanceOnTransactionCompletefalse bir işlem OperationBehaviorAttribute.TransactionScopeRequired varsa açıkça olarak ayarlamanız ConcurrencyModeReentrantgerektiğini unutmayın. Aksi takdirde varsayılan değeri ReleaseServiceInstanceOnTransactionComplete olduğundan truedoğrulama özel durumu oluşturulur.

çalışma zamanı davranışını değiştirebilen ve diğer özelliklerin ConcurrencyMode etkileşimi vardır. Bu etkileşimlerin tam açıklaması için bkz . Oturumlar, Tutarsızlık ve Eşzamanlılık.

Şunlara uygulanır