65.9K
CodeProject 正在变化。 阅读更多。
Home

三种 WCF 实例管理方式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (153投票s)

2010年6月6日

CPOL

6分钟阅读

viewsIcon

640249

downloadIcon

8333

三种 WCF 实例管理方式(每个调用、每个会话、单个)。

目录

引言

我们经常希望控制 WCF 服务对象在 WCF 服务器上的实例化方式。您需要控制 WCF 实例在服务器上保留多长时间。

WCF 框架提供了三种控制 WCF 实例创建的方式。在本文中,我们将首先尝试通过简单的代码示例来理解这三种 WCF 服务实例控制方式,以及如何实现它们。最后,我们将比较何时以及在何种情况下使用它们。

为我所有的 .NET 朋友准备了一本小型电子书,涵盖了 WCF、WPF、WWF、AJAX、Core .NET、SQL 等主题,您可以在此下载:此处

WCF 服务对象实例化基础

在正常的 WCF 请求和响应通信中,会发生以下一系列操作:

  • WCF 客户端向 WCF 服务对象发出请求。
  • 实例化 WCF 服务对象。
  • WCF 服务实例处理请求并将响应发送给 WCF 客户端。

以下是 WCF 请求和响应工作方式的图示。

以下是创建 WCF 实例的不同方式:

  • 在每次 WCF 客户端方法调用时创建一个新的 WCF 服务实例。
  • 为每个 WCF 客户端会话只创建一个 WCF 服务实例。
  • 只创建一个全局 WCF 服务实例供所有 WCF 客户端使用。

为了满足上述场景,WCF 提供了三种控制 WCF 服务实例的方式:

  • 每个调用
  • 每个会话
  • 单个实例

每个调用实例模式

当我们将 WCF 服务配置为每个调用时,每次通过 WCF 代理客户端调用方法时都会创建新的服务实例。下图以图示形式展示了这一点:

  • WCF 客户端发出第一个方法调用(方法调用 1)。
  • 在服务器上为该方法调用创建一个新的 WCF 服务实例。
  • WCF 服务处理请求并发送响应,然后 WCF 实例被销毁并交给垃圾回收器进行清理。
  • 现在,假设 WCF 客户端发出第二次方法调用,会创建一个新实例,处理请求,然后销毁 WCF 实例。

换句话说,每次调用 WCF 客户端方法时,都会创建一个 WCF 服务实例,并在请求处理完毕后销毁。

如何实现 WCF 每个调用实例化

为了指定实例化模式,我们需要在 ServiceBehavior 属性中提供 InstanceContextMode 值,如下所示。此属性需要应用于 Service 类。在下面的代码片段中,我们将 intCounter 声明为类级别的变量,并在调用 Increment 方法时将类计数器加一。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Percall)] 
public class Service : IService
{
    private int intCounter;

    public int Increment()
    {
        intCounter++
        return intCounter;
    }
}

在客户端,我们使用 WCF 客户端并调用两次 Increment 方法。

ServiceReference1.ServiceClient obj = new ServiceReference1.ServiceClient(); 
MessageBox.Show(obj.Increment().ToString());
MessageBox.Show(obj.Increment().ToString());

即使我们调用了两次 Increment 方法,得到的值仍然是 '1'。换句话说,每次调用 WCF 服务实例的方法时都会创建一个 WCF 服务实例,因此值将始终为一。

每个会话实例模式

我们经常需要在方法调用之间或在特定会话中维护状态。对于这些场景,我们需要将服务配置为每个会话。在每个会话模式下,只会为一次会话交互创建一个 WCF 服务对象的实例。下图以图示形式解释了这一点:

  • 客户端创建 WCF 服务的代理并进行方法调用。
  • 创建一个 WCF 服务实例来处理方法响应。
  • 客户端在同一会话中发出另一个方法调用。
  • 同一个 WCF 服务实例处理该方法调用。
  • 当客户端完成其活动时,WCF 实例会被销毁并交给垃圾回收器进行清理。

如何实现每个会话实例化

要将服务配置为每个会话,我们需要使用 InstanceContextMode 对象中的 PerSession 值来配置 ServiceBehavior 属性。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
public class Service : IService
{
    private int intCounter;
    public int Increment()
    {
        intCounter++
        return intCounter;
    }
}

在客户端,当我们运行下面的客户端代码时,在客户端代码执行完毕后,您应该会看到值 '2'。我们调用了两次方法,所以看到的值是二。

ServiceReference1.ServiceClient obj = new ServiceReference1.ServiceClient(); 
MessageBox.Show(obj.Increment().ToString());
MessageBox.Show(obj.Increment().ToString());

单个实例模式

我们经常希望为所有 WCF 客户端创建一个全局 WCF 实例。要创建 WCF 服务的单个实例,我们需要将 WCF 服务配置为 Single 实例模式。下面是单个实例模式如何工作的简单图示:

  • WCF 客户端 1 向 WCF 服务发出方法调用请求。
  • 创建一个 WCF 服务实例并处理该请求。WCF 服务实例不会被销毁,而是被保留以服务其他请求。
  • 现在,假设另一个 WCF 客户端,例如客户端 2,发出方法调用请求。
  • 由 WCF 客户端 1 创建的同一个 WCF 实例用于处理 WCF 客户端 2 的请求。换句话说,只有一个全局 WCF 服务器服务实例用于处理所有客户端请求。

如何实现单个实例模式

为了创建 WCF 服务的单个实例,我们需要将 InstanceContextMode 指定为 Single

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class Service : IService
{
}

如果从不同的客户端调用 WCF 服务,您会看到计数器在递增。计数器成为一个全局变量。

何时应使用每个调用、每个会话和单个模式?

每个调用

  • 您需要无状态服务。
  • 您的服务包含大量资源,例如连接对象和大量内存对象。
  • 可伸缩性是首要要求。您希望拥有一个横向扩展的体系结构。
  • 您的 WCF 函数以单线程模型调用。

每个会话

  • 您希望在 WCF 调用之间维护状态。
  • 您有一个纵向扩展的体系结构。
  • 轻量级资源引用。

单个

  • 您希望通过 WCF 服务共享全局数据。
  • 可伸缩性不是问题。

参考文献

源代码

您可以从 此处 下载本教程的源代码。

进一步阅读,请观看下面的面试准备视频和分步视频系列。

© . All rights reserved.