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. 有关详细信息,请参阅ConcurrencyModeFor 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.

示例

下面的代码示例演示如何使用单个、 可重入和多个之间的差别。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;
  }
}

注解

ConcurrencyModeConcurrencyMode 属性一起使用,可指定服务类是支持单线程还是多线程操作模式。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.

下表显示了当 Windows Communication Foundation (WCF) 允许了一个操作,以调用时另一个正在进行,具体取决于ConcurrencyModeThe 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.

适用于