ServiceBehaviorAttribute.ConcurrencyMode ServiceBehaviorAttribute.ConcurrencyMode ServiceBehaviorAttribute.ConcurrencyMode ServiceBehaviorAttribute.ConcurrencyMode Property

定義

サービスが、1 つのスレッド、複数のスレッド、または再入呼び出しをサポートするかどうかを示す値を取得または設定します。Gets or sets whether a service supports one thread, multiple threads, or reentrant calls.

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

プロパティ値

ConcurrencyMode 値の 1 つ。既定値は Single です。One of the ConcurrencyMode values; the default is Single.

例外

次のコード例は、SingleReentrant、および Multiple の各使用方法の相違を示します。The following code example demonstrates the different between using Single, Reentrant, and Multiple. このサンプルは、その背後にある実際の実装なしでコンパイルできなかったはスレッドの保証を Windows Communication Foundation (WCF) は、そのため、操作コードの種類を示します。This sample does not compile without a real implementation behind it, but does demonstrate the kind of threading guarantees that Windows Communication Foundation (WCF) makes and what that means for your operation code.

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

注釈

このプロパティは、サービスのインスタンスが 1 つのスレッドまたは同時に実行する複数のスレッドを処理できるかどうか、またシングル スレッドの場合は再入をサポートしているかどうかを示します。This property indicates whether an instance of a service can handle one thread or multiple threads that execute concurrently, and if single-threaded, whether reentrancy is supported.

注意

ConcurrencyMode プロパティは、他のいくつかの設定と相互関係があります。The ConcurrencyMode property interacts with some other settings. たとえば、InstanceContextMode 値を Single に設定した場合は、ConcurrencyMode 値を Multiple に設定しない限り、サービスが一度に処理できるのは 1 つのメッセージだけです。For example, if the InstanceContextMode value is set to Single the result is that your service can only process one message at a time unless you also set the ConcurrencyMode value to Multiple. このプロパティと ServiceContractAttribute.SessionMode プロパティを組み合わせて、特定の動作を設定することもできます。This property also produces behavior in combination with the ServiceContractAttribute.SessionMode property. 詳細については、次を参照してください。セッション、インスタンス化、および同時実行します。For details, see Sessions, Instancing, and Concurrency.

ConcurrencyModeSingle に設定すると、サービスのインスタンスを 1 つずつのスレッド実行に制限するようシステムに指示します。それにより、スレッドの問題に対応することから解放されます。Setting ConcurrencyMode to Single instructs the system to restrict instances of the service to one thread of execution at a time, which frees you from dealing with threading issues. Multiple の値は、サービス オブジェクトを複数のスレッドで一度に実行できることを示します。A value of Multiple means that service objects can be executed by multiple threads at any one time. この場合は、開発者がスレッド セーフを確保する必要があります。In this case, you must ensure thread safety.

Reentrant また同時に 1 つのスレッドへのアクセスを制限します。操作の処理中に他のメッセージに入ることは、操作します。Reentrant also restricts access to a single thread at a time; while the operation is processing, no other message can enter the operation. 操作の進行中に、別のサービスに対する呼び出しがコール アウトした場合は、操作に対する現在のメッセージのロックは失われ、他のメッセージの処理が可能になります。If during the operation a call to another service leaves, the current message loses the lock on the operation, which is free to process other messages. サービスのコール アウトが戻ると、ロックが再度確立され、元のメッセージを最後まで処理するか、別のコール アウトが発生するまで処理を続行できます。When the service call out returns, the lock is reestablished and the original message can continue processing to its conclusion or until another call out of the operation occurs.

重要

でもSingleインスタンスの制限の同時実行の 1 つのスレッドにサービスを設定する必要もMaxConcurrentCallsメッセージの順序のないことを保証するには 1 です。Even though Single restricts instances of the service to one thread of execution at a time, you must also set MaxConcurrentCalls to 1 to guarantee no out-of-order messages.

また、コール アウト前に一貫性のあるオブジェクトの状態のままにする必要があり、操作のローカル データがコール アウト後も有効であることを確認する必要があります。Also, it is your responsibility to leave your object state consistent before callouts and you must confirm that operation-local data is valid after callouts. サービス インスタンスは、WCF チャネルを介して別のサービスを呼び出すことによってのみロックを解除されます。Note that the service instance is unlocked only by calling another service over a WCF channel. この場合、呼び出されたサービスはコールバック経由で最初のサービスに再入できます。In this case, the called service can reenter the first service via a callback. 最初のサービスが再入可能でない場合、以降の呼び出しはデッドロック状態になります。If the first service is not reentrant, the sequence of calls results in a deadlock. 詳細については、「ConcurrencyMode」を参照してください。For details, see ConcurrencyMode.

処理中の操作から送信呼び出しが行われている間は、その操作にとってローカルではないデータを変更することができます。During any outbound call from a processing operation, data not local to the operation can be modified. ローカル状態のデータは、元のメッセージの処理を再開するときに有効であることが保証されています。この結果、開発者は、送信呼び出しを行う前に、ローカル以外のデータが他の受信呼び出しにとって有効であることを保証し、送信呼び出しが戻った後で、ローカル以外のデータを再検証する必要があります。(Local state data is guaranteed to be valid when the original message resumes processing.) As a result, before your outbound call you must ensure that non-local data is valid for other incoming calls and revalidate non-local data after the outbound call returns.

次の擬似コードは、再入を正常にサポートするために必要なパターンを示しています。The following pseudo-code illustrates the required pattern for successful reentrant support.

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

ConcurrencyModeReentrant のときに、送信呼び出しで Begin/End 非同期呼び出しパターンを使用すると、例外が発生します。Using the Begin/End asynchronous call pattern for an outbound call when the ConcurrencyMode is Reentrant triggers an exception. 非同期の送信呼び出しでは、ConcurrencyModeMultiple である操作を必要とします。この場合は、開発者が同期問題を処理する必要があります。Asynchronous outbound calls require an operation in which ConcurrencyMode is Multiple, in which case you must handle synchronization issues.

通常、コンカレンシー モードに違反するインスタンスにメッセージが届いた場合は、そのインスタンスが使用可能になるまで、またはタイムアウトになるまで、メッセージは待機します。Generally, if a message arrives for an instance that violates its concurrency mode, the message waits until the instance is available, or until it times out.

さらに、ConcurrencyModeSingle に設定され、再入可能呼び出しが、インスタンスが解放されるまで待機する間ブロックされた場合、システムはデッドロックを検出し、例外をスローします。In addition, if the ConcurrencyMode is set to Single and a reentrant call is blocked while waiting for the instance to be freed, the system detects the deadlock and throws an exception.

注意

InvalidOperationException プロパティに ReleaseServiceInstanceOnTransactionComplete が設定されているときに、trueConcurrencyMode の場合は、実行時に Single がスローされます。A InvalidOperationException is thrown at runtime if ReleaseServiceInstanceOnTransactionComplete is true when the ConcurrencyMode property is set to Single.

ReleaseServiceInstanceOnTransactionComplete が true に設定された操作があるときに falseOperationBehaviorAttribute.TransactionScopeRequired に設定する場合は、ConcurrencyModeReentrant に明示的に設定する必要があることに注意してください。Note that you must explicitly set ReleaseServiceInstanceOnTransactionComplete to false if there is an operation with OperationBehaviorAttribute.TransactionScopeRequired set to true and you set ConcurrencyMode to Reentrant. ReleaseServiceInstanceOnTransactionComplete の既定値は true であるため、この設定を行わなかった場合は検証例外がスローされます。Otherwise a validation exception is thrown because the default value of ReleaseServiceInstanceOnTransactionComplete is true.

ConcurrencyMode と他のプロパティの間には、ランタイム動作を変更する可能性がある相互関係があります。There is an interaction of the ConcurrencyMode and other properties that can alter runtime behavior. これらの相互作用の詳細については、次を参照してください。セッション、インスタンス化、および同時実行します。For a complete description of these interactions, see Sessions, Instancing, and Concurrency.

適用対象