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

ASP.NET 中的高级数据缓存功能

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.09/5 (23投票s)

2004年5月23日

5分钟阅读

viewsIcon

101142

一篇关于 ASP.NET 数据缓存功能的文章。

引言

本文简要介绍了不同类型的缓存依赖项以及如何使用回调方法自动重新填充过期的缓存。

数据缓存

ASP.NET 具有一个功能齐全的缓存引擎,应用程序可以使用它将任意对象存储在内存中。此机制通过 Cache 类实现,该类的一个实例存在于已配置的每个 Web 服务器应用程序中。应用程序缓存提供了一个简单的字典接口,使用键/值对,让您可以从缓存中存储和检索对象。

应用程序缓存对应用程序是全局的,访问该应用程序的每个用户都可以访问缓存中的值(不要与会话混淆)。将项目放入缓存非常简单。就像向字典添加项目一样。

以下是将一个名为 dstEmployeeDataSet 添加到 Cache 并使用键名 myEmpDataset 的方法:

 Cache["myEmpDataset"] = dstEmployee

将项目插入缓存

Add 方法允许您将项目添加到缓存。如果缓存中已存在具有相同键的项目,Add 方法将忽略任何添加项目的调用。insert 方法在功能上与 Add 方法相同,但如果缓存中已存在具有相同键的项目,它会覆盖该项目。

我们来看看 insert 方法:

public void Insert(string key, object value,CacheDependency dependencies,
  DateTime absoluteExpiration,
  TimeSpan slidingExpiration,
  CacheItemPriority priority,
  CacheItemRemovedCallback onRemoveCallback );
  • value:要插入到缓存的对象。
  • key:用于引用对象的缓存键。
  • dependencies:项的文件或缓存键依赖项。当任何依赖项发生更改时,对象将失效并从缓存中删除。如果没有依赖项,此参数将包含一个空引用(在 Visual Basic 中为 Nothing)。
  • absoluteExpiration:插入的对象过期并从缓存中移除的时间。
  • slidingExpiration:插入的对象上次访问时间与该对象过期之间的时间间隔。如果此值为 20 分钟,则该对象将在上次访问后 20 分钟过期并从缓存中移除。
  • priority:对象相对于缓存中存储的其他项的成本,由 CacheItemPriority 枚举表示。缓存驱逐对象时使用此值;成本较低的对象会比成本较高的对象先从缓存中移除。
  • onRemoveCallback:一个委托,如果提供,当对象从缓存中移除时将被调用。您可以使用此来通知应用程序其对象已从缓存中删除。
Cache.Insert ("DSN", connectionString,new CacheDependency(“filepath”) 
  DateTime.Now.AddMinutes(2), 
  TimeSpan.Zero, 
  CacheItemPriority.High,
  new CacheItemRemovedCallback(this.RemovedCallback)
);

当我们将对象插入缓存时,我们可以设置依赖项和一个回调函数,该函数将在缓存过期时执行。CacheItemRemovedCallback 是一个委托,它定义了一个回调方法,用于在缓存项从 Cache 中移除时通知应用程序。现在,我们可以使用这两个功能做一些很酷的事情。我们将首先介绍设置依赖项。

什么是依赖项?

当我们将一个项目插入缓存时,我们可以根据其他资源(例如服务器上的物理文件、另一个缓存项或时间)来设置该项目的过期策略。我们缓存项所依赖的任何资源发生更改,都会导致我们的缓存项过期。

有三种类型的依赖项:

  • 基于文件的依赖项
  • 基于键的依赖项
  • 基于时间的依赖项
基于文件的依赖项

我们可以根据外部文件或文件集来设置缓存项的有效性。当此资源发生更改时,缓存对象将变得无效并从缓存中删除。

CacheDependency dependency = new CacheDependency(Server.MapPath("isbn.xml"));

对于多个文件依赖项,可以将包含文件名字符串数组传递给构造函数。

基于键的依赖项

基于键的依赖项允许您将一个缓存项与缓存中的另一个项关联,并在第二个项更改时使第一个项失效。以下代码片段演示了如何将项插入应用程序的 Cache 中,并依赖于另一个放置在缓存中的项的键。由于此方法使用数组语法,因此您必须定义要添加到 Cache 的项所依赖的键的数量。

String[] dependencyKey = new String[1];
dependencyKey[0] = "key1"; 
CacheDependency dependency = new CacheDependency(null, dependencyKey);

通过增加数组大小并将键添加到数组,可以使用多个键依赖项。

基于时间的依赖项。

基于时间的依赖项会在预定义时间过期该项。基于时间的依赖项有两种:绝对和滑动。我已在 insert 方法中解释了这两种。

为缓存项创建回调方法

除了设置键、文件或时间的依赖项外,我们还可以为缓存项关联一个回调方法。当缓存项过期时,此方法会自动调用。通过使用此功能,我们可以确保缓存项不会被删除,或者缓存会根据新数据进行更新。要实现回调通知,我们需要使用 CacheItemRemovedCallback 委托。在插入缓存项时,会将此委托的一个实例传递给 insert 方法。该委托的签名如下:

public delegate void CacheItemRemovedCallback( string key, 
    object value, CacheItemRemovedReason reason );
  • key:从缓存中移除的项的索引位置。
  • value:从缓存中移除的 object 项。
  • reason:项从缓存中移除的原因,由 CacheItemRemovedReason 枚举指定。

第三个参数对我们很重要。使用此参数,我们可以获取缓存项被移除的原因。CacheItemRemovedReason 枚举具有以下值:

  • DependencyChanged:项因文件或键依赖项更改而被从缓存中移除。
  • Expired:项因过期而被从缓存中移除。
  • Removed:项通过 Remove 方法调用或指定相同键的 Insert 方法调用而被从缓存中移除。
  • Underused:项因系统为了释放内存而将其移除,因此被从缓存中移除。

创建回调方法来处理过期事件的示例

public void RemovedCallback(String k, 
       Object v,CacheItemRemovedReason r) {
// Write code here to check the reason for expiration
// and to repopulate using new values
}

关注点

世界上没有什么东西是 100% 好处的。缓存也有其阴暗的一面。启用缓存时,它会占用宝贵的系统资源,很容易耗尽所有内存。当服务器内存不足时,缓存的内容会自动清除。清除是根据缓存项的优先级和缓存项的使用情况等因素进行的。我们可以在 insert 方法中使用 CacheItemPriority 枚举来设置每个缓存项的优先级。

当使用回调方法重新填充缓存时,请检查 CacheItemRemovedReason 参数。如果原因是 RemovedUnderused,则不要尝试重新填充。

历史

文章版本 1.0

© . All rights reserved.