ConcurrencyMode ConcurrencyMode ConcurrencyMode ConcurrencyMode Enum

定義

サービス クラスがシングルスレッド モードまたはマルチスレッド モードの操作をサポートするかどうかを指定します。Specifies whether a service class supports single-threaded or multi-threaded modes of operation.

public enum class ConcurrencyMode
public enum ConcurrencyMode
type ConcurrencyMode = 
Public Enum ConcurrencyMode
継承
ConcurrencyModeConcurrencyModeConcurrencyModeConcurrencyMode

フィールド

Multiple Multiple Multiple Multiple 2

サービス インスタンスはマルチスレッドです。The service instance is multi-threaded. 同期保証は行われません。No synchronization guarantees are made. サービス オブジェクトは他のスレッドによっていつでも変更される可能性があるため、開発者が同期と状態の整合性を常に処理する必要があります。Because other threads can change your service object at any time, you must handle synchronization and state consistency at all times.

Reentrant Reentrant Reentrant Reentrant 1

サービス インスタンスはシングル スレッドであり、再入呼び出しを受け入れます。The service instance is single-threaded and accepts reentrant calls. 再入可能サービスは別のサービスを呼び出したときの呼び出しを受け入れます。したがって、開発者は、オブジェクトの状態をコール アウト前の状態と必ず一致させ、操作のローカル データがコール アウト後も有効であることを確認する必要があります。The reentrant service accepts calls when you call another service; it is therefore 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.

Single Single Single Single 0

サービス インスタンスはシングルスレッドであり、再入呼び出しを受け入れません。The service instance is single-threaded and does not accept reentrant calls. InstanceContextMode プロパティが Single のときに、インスタンスが呼び出しを処理している間に別のメッセージが到着した場合は、到着したメッセージは、サービスが使用可能になるか、メッセージがタイムアウトするまで待機する必要があります。If the InstanceContextMode property is Single, and additional messages arrive while the instance services a call, these messages must wait until the service is available or until the messages time out.

次のコード例は、Single、リエントラント、および Multiple の使用方法の違いを示しています。The following code example demonstrates the different between using Single, Reentrant, and Multiple. このサンプルは、その背後に実際の実装がないとコンパイルされませんが、WCF が行うスレッド保証の種類と、操作コードの意味を示しています。This sample does not compile without a real implementation behind it, but does demonstrate the kind of threading guarantees that 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;
  }
}

注釈

ConcurrencyMode は、ConcurrencyMode プロパティと組み合わせて使用し、サービス クラスがシングルスレッド モードまたはマルチスレッド モードの操作をサポートするかどうかを指定します。ConcurrencyMode is used in conjunction with the ConcurrencyMode property to specify whether a service class supports single-threaded or multi-threaded modes of operation. シングルスレッド操作は、再入可能または非再入可能のどちらも可能です。A single-threaded operation can be either reentrant or non-reentrant.

次の表は、に応じてConcurrencyMode、別の操作が進行中のときに、Windows Communication Foundation (WCF) が操作を呼び出せるようにする場合を示しています。The following table shows when Windows Communication Foundation (WCF) permits an operation to be invoked while another one is in progress, depending upon the ConcurrencyMode.

ConcurrencyMode 値ConcurrencyMode Value 新しい操作の呼び出しの可否Can a new operation be invoked?
SingleSingle 不可Never.
再入Reentrant 別のサービスまたはコールバックを呼び出し中のみ可能Only while invoking another service or a callback.
複数Multiple 常に。Always.

適用対象