ConcurrencyMode 列挙型

定義

サービス クラスがシングルスレッド モードまたはマルチスレッド モードの操作をサポートするかどうかを指定します。

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

フィールド

Multiple 2

サービス インスタンスはマルチスレッドです。 同期保証は行われません。 サービス オブジェクトは他のスレッドによっていつでも変更される可能性があるため、開発者が同期と状態の整合性を常に処理する必要があります。

Reentrant 1

サービス インスタンスはシングル スレッドであり、再入呼び出しを受け入れます。 再入可能サービスは別のサービスを呼び出したときの呼び出しを受け入れます。したがって、開発者は、オブジェクトの状態をコール アウト前の状態と必ず一致させ、操作のローカル データがコール アウト後も有効であることを確認する必要があります。 サービス インスタンスは、WCF チャネルを介して別のサービスを呼び出すことによってのみロックを解除されます。 この場合、呼び出されたサービスはコールバック経由で最初のサービスに再入できます。 最初のサービスが再入可能でない場合、以降の呼び出しはデッドロック状態になります。 詳細については、「ConcurrencyMode」を参照してください。

Single 0

サービス インスタンスはシングルスレッドであり、再入呼び出しを受け入れません。 InstanceContextMode プロパティが Single のときに、インスタンスが呼び出しを処理している間に別のメッセージが到着した場合は、到着したメッセージは、サービスが使用可能になるか、メッセージがタイムアウトするまで待機する必要があります。

次のコード例は、Single、Reentrant、Multiple の使用の違いを示しています。 このサンプルは、実際の実装なしでコンパイルするのではなく、WCF が行うスレッド処理の種類と、それが操作コードに対して何を意味するのかを示しています。

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 プロパティと組み合わせて使用し、サービス クラスがシングルスレッド モードまたはマルチスレッド モードの操作をサポートするかどうかを指定します。 シングルスレッド操作は、再入可能または非再入可能のどちらも可能です。

次の表は、 に応じて、Windows Communication Foundation (WCF) が別の操作の実行中に操作を呼び出すタイミングを ConcurrencyMode示しています。

ConcurrencyMode 値 新しい操作の呼び出しの可否
Single 不可
リエントラント 別のサービスまたはコールバックを呼び出し中のみ可能
複数 常に。

適用対象