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

探索缓存:使用 Enterprise Library 4.1 缓存应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (48投票s)

2010 年 1 月 10 日

CPOL

14分钟阅读

viewsIcon

252695

本文介绍 Caching Application Block - Enterprise Library 4.1 的使用。

目录

简介

如果我们考虑应用程序的性能,缓存是最重要的因素之一。大多数应用程序都需要缓存实现来提高性能。Caching Application Block 提供了一个灵活且可扩展的缓存框架,其中包含一套 API,可用于应用程序的任何层。它支持内存、数据库或隔离存储来存储缓存数据。我们可以在 Web 应用程序和 Windows 应用程序中使用它。使用 Caching Application Block 实现缓存可以提高应用程序的性能,同时缩短开发时间和成本。这个应用程序块提供了所有类型的函数,例如添加、删除和管理缓存过期。在本文中,我解释了如何在 ASP.NET Web 应用程序中使用 Enterprise Library 4.1 的 Caching Application Block。但正如我之前所说,Caching Application Block 非常通用,可以在不同的应用程序中使用,而无需更改一行代码。换句话说,我们可以说 Enterprise Library Caching Application Block 提供了一个现成的缓存框架。希望本文对大家有所帮助。请提供您宝贵的建议和反馈,以改进我的文章。

在哪里可以使用 Caching Application Block?

Enterprise Library Caching Application Block 是一个现成的缓存框架,可用于各种应用程序,例如:

  • ASP.NET Web 应用程序
  • Windows Forms
  • 控制台
  • Windows 服务
  • Enterprise Services
  • Web服务

这个缓存应用程序块具有内置功能,如将项添加到缓存、从缓存中移除、缓存过期设置等。它还可根据您的需求进行扩展。

在本文中,我有一个演示代码,这是一个 ASP.NET Web 应用程序。

安装 Enterprise Library 4.1

首先,我们需要安装 Enterprise Library,然后才能开始使用任何应用程序块。目前,Enterprise Library 的最新版本是 4.1。本文基于相同的版本。您可以轻松地从 Enterprise Library 4.1-October 2008 下载并安装 Enterprise Library。

Microsoft Enterprise Library 是一系列可重用的应用程序块,旨在帮助软件开发人员应对常见的企业开发挑战。此版本包括缓存、加密、数据访问、异常处理、日志记录、策略注入、安全、验证和 Unity。

开发环境

为了演示本文和开发示例代码,我使用了以下环境:

  • Windows Vista Home Premium
  • Visual Studio 2010 Professional - Beta 2
  • .NET Framework 4.0
  • Enterprise Library 4.1

您可以在自己的环境中进行开发。您可以在此处查看 Enterprise Library 4.1 的系统要求。

使用 Enterprise Library 配置管理器

Enterprise Library 的 API 基于 XML 配置。应用程序配置文件包含所有与应用程序块相关的信息。由于这是 XML 配置,我们可以手动更改文件中的所有内容,但很难记住所有配置和属性。Microsoft 提供了 Enterprise 配置 UI 控制台,可以使用 UI 配置应用程序块。

安装 Enterprise Library 4.1 后,您可以在已安装位置的Bin 目录中找到 Enterprise Library 配置管理器。在我的情况下,它位于“C:\Program Files (x86)\Microsoft Enterprise Library 4.1 - October 2008\Bin”。运行EntLibConfig.exe。或者,您可以转到“开始”>“程序文件”>“Microsoft Patterns and Practices”>“Enterprise Library”>“Enterprise Library Configuration”。将出现以下屏幕:

配置 Caching Application Block

现在,单击“文件”>“打开应用程序”。选择您的 ASP.NET Web 应用程序的“web.config”。

默认情况下,Enterprise Library 配置已添加 Data Access Application Block 设置。我们可以通过右键单击 > 移除来轻松删除任何配置设置。

现在,我们可以通过右键单击“根”>“新建”>“Caching Application Block”来添加“Caching Application Block”。

一个新的配置节“Caching Application Block”将自动添加到配置文件中。

在配置管理器中保存配置。现在打开 Web 应用程序并检查web.config 文件中的更改。添加 Caching Application Block 使用 Enterprise Application Manager 后,您将在web.config 文件中找到已添加以下Config节。

使用 Caching Application Block

添加引用

由于缓存应用程序块是一组预定义的代码,并在框架中定义,因此我们需要向应用程序添加一些引用。它们是Microsoft.Practices.EnterpriseLibrary.Caching.dllMicrosoft.Practices.EnterpriseLibrary.common.dll。这两个足以使用 Caching Application Block。

添加引用后,我们必须添加一个命名空间来使用 Caching Application Block。它们是:

using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Common;

这就是关于添加引用和命名空间的所有内容。现在,让我们看看如何执行所有缓存操作,例如将数据添加到缓存、从缓存中移除、显示缓存中的数据、缓存过期等。

在执行任何缓存操作之前,我们需要初始化CacheManager对象。

初始化 Cache Manager

ICacheManager 是我们的应用程序和 Caching Application Block 之间的主要接口。要创建CacheManager对象的实例,应用程序会使用CacheFactory类,该类又使用CacheManagerFactory类。CacheManagerFactory类创建实现CacheManager对象所需的所有内部类。

ICacheManager _objCacheManager = CacheFactory.GetCacheManager();

GetChcheManager 有一个重载方法;默认情况下,它返回默认的CacheManger实例。我们还可以指定在配置文件中指定的缓存管理器名称,例如:

ICacheManager _objCacheManager = CacheFactory.GetCacheManager("MyCacheManager");

每当我们从应用程序中调用 GetCacheManager() 方法时,它将始终返回相同的缓存管理器实例。因此,如果我们在应用程序中使用多个缓存管理器,我们需要在 CacheFactory.GetCacheManager(<name>); 中提供缓存管理器的名称。

将项添加到缓存

现在我们有了CacheManager的实例。CacheManager提供了一个Add()方法来将新的CacheItem添加到缓存。默认情况下,它接受两个参数:String KeyObject Value

以下是演示如何将CacheItem添加到缓存的示例代码片段:

//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
//Add a new CacheItem to Cache
_objCacheManager.Add("Name", "Abhijit");

其中Name是我的密钥,"Abhijit"是对象值。这是一个非常简单的例子。我们甚至可以将复杂对象存储在缓存中。看看下面使用简单Student类的示例:

/// <summary>
/// Student Class
/// </summary>
public class Student
{
    #region PrivateVariable
    //Studnet Name
    private string name;
    //Student Roll
    private int roll;
    #endregion PrivateVariable

    #region PrivateProp
    private int Roll
    {
        get
        {
            return roll;
        }

        set
        {
            roll = value;
        }
    }
    private string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
        }
    }
    #endregion PrivateProp

    /// <summary>
    /// Student Constructor
    /// </summary>
    /// <param name=""roll"" />Roll
    /// <param name=""name"" />Name
    public Student(int roll, string name)
    {
        this.Roll = roll;
        this.Name = name;
    }
}

Student类代码非常简单,我只使用一个带参数的构造函数来创建学生实例。下面的代码展示了如何将学生对象存储在缓存中。

//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
// Create Instance of Student Class
Student _objStud = new Student(10, "Abhijit");
// Add Studnet Object as Cache Item
_objCacheManager.Add("Student", _objStud);

由于缓存用于大规模数据存储,我们可以将DataSetDataTable作为CacheItem存储在缓存中。下面的示例展示了如何将DataSet存储在CacheItem中。

_objCacheManager.Add("LargeData", _objDataSet);

到目前为止,我讨论了Add()方法的基本版本,它只有两个参数。正如我已经提到的,Add()方法有一个额外的重载方法,可以将缓存功能扩展到更大的范围。这些重载方法有五个参数:keyvaluescavengingPriorityrefreshActionexpirations

KeyValue与前面描述的相同。现在我们有了三个新东西:

  • CacheItemPriority
  • ICacheItemRefreshAction
  • ICacheItemExpiration[]

CacheItemPriority枚举允许您指定缓存项的优先级。默认情况下它是NormalICacheItemRefreshAction 用于当您想在刷新缓存集合中的缓存项时执行某些操作。ICacheItemExpiration 允许最终用户实现自己的缓存项过期方案。如果我们要忽略它们,可以将其设置为null。我将在后面的部分详细解释它们。

从缓存中移除项

从缓存中移除项非常容易实现。CacheManager提供了一个Remove()方法来从缓存中移除CacheItem。此方法没有重载方法,只接受一个参数Key。如果密钥存在,CacheItem将自动从CacheItems中移除,否则此方法将不起作用。

//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
//Remove Item From Cache
_objCacheManager.Remove("Name");

这对所有类型的CacheItem都一样。我们之前看到了如何将DataSet存储在缓存中。如果我们想移除它,只需要这样做:

_objCacheManager.Remove("LargeData");

注意:我们必须确保对于所有密钥,CacheManager的实例都是相同的。

从缓存中移除所有项

我们可以使用CacheManagerFlush()方法从缓存中移除所有项。

_objCacheManager.Flush();

在此操作期间,如果发生错误,缓存项将保持不变。

检查密钥是否存在

如果我们使用多个CacheManager,或者我们想检查密钥是否属于特定的缓存集合,我们可以使用CacheManagerContains()方法。

if(_objCacheManager.Contains("Name"))
{
  //Do something
}
else
{
 // Do Something
}

从缓存中检索项

将元素添加到缓存后,下一步是检索缓存集合中的缓存元素。CacheManager提供了一个名为GetData()的方法。GetData()只接受一个参数Key并返回缓存数据。但在检索缓存元素时,我们必须确保将对象正确地进行类型转换。例如,如果我们已将DataSet作为对象存储在缓存中,在检索时,我们必须确保进行相同的类型转换。

//Create Instance of CacheManager 
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
// Create Instance of Student Class
Student _objStud = new Student(10, "Abhijit");
// Add Studnet Object as Cache Item
_objCacheManager.Add("Student",_objStud);

// Check If Key is in Cache Collection
if(_objCacheManager.Contains("Student"))
{
  // Retreive Cached Student Data
  Student _objCachedStudent = 
    (Student)_objCacheManager.GetData("Student");
}

缓存过期

Microsoft Caching Application Block 提供了缓存过期功能的极大便利。为此,我们需要添加以下命名空间:

using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

添加命名空间将为我们提供以下类,以使用 Application Block 实现缓存过期。

  • 绝对时间
  • ExtendedFormat
  • ExtendedFormatTime
  • 文件依赖
  • 永不过期
  • SlidingTime

绝对时间

绝对时间通过指定项从缓存项集合中过期的绝对时间来定义缓存项的生命周期。绝对过期以完整时间格式(hh:mm:ss)指定。对象将在指定时间从缓存中过期。

例如

AbsoluteTime _AbsoulteTime = new AbsoluteTime(TimeSpan.FromHours(1));
_objCacheManager.Add("Student", _objStud, 
    CacheItemPriority.Normal, null, _AbsoulteTime);

ExtendedFormatExtendFormatTimeAbsoluteTime 配置非常相似。我将不再详细介绍这两个。让我们从 FileDependency 开始。

文件依赖

当磁盘上的文件发生更改时,基于文件的依赖关系会使特定缓存项失效。当我们需要在文件或数据库发生更改时更新缓存数据时,这非常有用。

FileDependency _objFileDependency=new FileDependency("MyFile.XML");
_objCacheManager.Add("Student", _objStud, CacheItemPriority.Normal, null, _objFileDependency);

根据给出的示例,如果“MyFile.xml”有任何更改,则_objStud将从缓存集合中移除。有时,当我们需要在文件更改时更新缓存数据时,这非常有用。

永不过期

如果我们将缓存过期策略设置为永不过期,则数据将存储在缓存集合中,直到我们使用CacheManager.Remove()移除缓存项。当我们在CacheManager.Add()方法中只使用键和值参数时,缓存对象将设置为永不过期模式。

滑动

滑动会在每次请求时重置缓存中项的过期时间。当缓存中的项需要保持有效,只要来自各种客户端的对该项的请求不断出现时,这一点就很有用。这意味着该项将在自上次访问该项以来经过指定时间后过期。默认时间是 2 分钟。

SlidingTime _objSlidingTime = new SlidingTime(TimeSpan.FromMinutes(5));
_objCacheManager.Add("Student", _objStud, CacheItemPriority.Normal, null, _objSlidingTime);

使用多个过期策略

我已经讨论了CacheManager.Add()方法,它有一个额外的重载方法,该方法接受五个参数。其中一个参数是ICacheItemExpiration。如果您查看详细信息,参数的类型是params,所以使用它,我们可以为缓存集合设置多个过期策略。下面是一个示例:

//Creating Absolute Time Expiration
AbsoluteTime _AbsoulteTime = new AbsoluteTime(TimeSpan.FromHours(1));
//Creating FileDependecy Object
FileDependency _objFileDependency=new FileDependency("MyFile.XML");
// Using ICacheItemExpiration To Set multiple Cache Expiration policy
_objCacheManager.Add("Student", _objStud, CacheItemPriority.Normal, 
   null, new ICacheItemExpiration[] { _AbsoulteTime, _objFileDependency });

因此,_objStud将根据两个过期策略从缓存集合中移除。

实现 ICacheItemRefreshAction

ICacheItemRefreshActionCacheManager.Add() 方法的 RefreshAction 参数的一部分。refreshAction 参数允许传入一个对象,该对象将在缓存对象过期时执行某些操作来更新它。如果您想在缓存过期时执行某些操作,这一点非常有用。

public class CacheLogPolicy : ICacheItemRefreshAction
{
    // Implement Referesh Method of interface ICacheItemRefreshAction
    public void Refresh(string removedKey, object expiredValue, 
           CacheItemRemovedReason removalReason)
    {
      // Log The Information Or We can do some other stuff also
    }

}

现在,在 CacheManager.Add() 方法中设置刷新操作的参数如下:

_objCacheManager.Add("Student", _objStud, 
    CacheItemPriority.Normal, new CacheLogPolicy(),null);

Caching Application Block 中的数据存储

每个缓存管理器都可以配置为仅在内存中存储数据,也可以将数据存储在持久存储中。Caching Application Block 提供以下存储位置:

  • 内存 / Null 后备存储
  • 数据库缓存存储
  • 隔离存储缓存
  • 自定义缓存存储

内存 / Null 后备存储

Caching Application Block 的默认存储位置是内存,它将后备存储值设置为nullbackingstore。Null 存储的配置设置为:backingStoreName="Null Storage"

数据库缓存存储

数据缓存存储使用数据库来存储缓存数据。这些缓存数据是持久数据。通常,另一个称为“Data Access Application Block”的 Enterprise Application Block 用于将缓存数据存储在数据库中。我们可以通过“Cache Manger”>“New”>“Database Cache Storage”添加“Data Storage”。

当我们在 Enterprise Library 配置中使用数据缓存存储时,它会自动在 Cache Manager 中添加“Data Cache Storage”,并添加“Data Access Application Block”。

现在,我们需要配置数据应用程序块来存储数据库缓存数据。配置 Data Application Blocks 意味着提供数据库服务器名称、连接字符串等。我将很快撰写另一篇文章来演示如何使用“Data Access Application Block”来存储“Database Cache Data”。如果您熟悉“Data Access Application Blocks”,则可以轻松实现它。

隔离存储缓存

要使用隔离存储,我们需要在配置中提供“分区名称”。分区名称将标识隔离存储中缓存管理器的存储区域。

我将分区名称称为“CacheIsolated”。下图显示了相应的web.config条目:

通常,当我们需要数据持久化且数据量较少时,隔离存储非常有用。

自定义缓存存储

除了内存、数据库和隔离存储之外,我们还可以创建自己的自定义缓存存储来持久化缓存数据。我们可以像数据库或隔离存储一样添加“Custom Cache Storage”。我们需要创建一个实现IBackingStore接口的自定义提供程序。

Caching Application Block 的通用配置

要使用 Caching Application Block,我们需要了解一些通用配置设置。它们是:

  • expirationPollFrequencyInSeconds
  • maximumElementsInCacheBeforeScavenging
  • numberToRemoveWhenScavenging

这些通用设置可以在 Enterprise Library 配置管理器和应用程序web.config中找到。

expirationPollFrequencyInSeconds

过期轮询频率用于检查哈希表中的CacheItems,以查看项是否已过期。Caching Application Block 中的所有过期策略都由BackgroundScheduler处理。轮询频率的默认值为 60 秒。

maximumElementsInCacheBeforeScavenging

回收意味着当内存不足时,缓存会尝试移除不常用或不重要的项。顾名思义,此设置用于设置回收策略。它定义了在项被回收出缓存之前缓存中的最大元素数量。默认值为“1000”。

numberToRemoveWhenScavenging

在回收过程中,numberToRemoveWhenScavenging 设置中定义的移除项数量将从缓存中移除。从缓存中移除回收项的默认值为“10”。

摘要

本文使用 Enterprise Library 4.1 介绍了 Caching Application Block 的使用。虽然这不是一个新话题,但我已尽力解释了与 Caching Application Block 相关的所有重要内容。本文主要基于理论概念。在下一篇文章中,我将介绍 Caching Application Block 的一些实际实现,例如 Database Storage Caching Application Block。

希望本文能帮助您开始使用 Caching Application Block。请提供您宝贵的建议和反馈,以改进文章。

参考和进一步学习

历史

  • 初次发布 - 2010 年 1 月 10 日。
© . All rights reserved.