不想引入Redis,你可以试试MemoryCache实现内存缓存

2023年 9月 6日 94.5k 0

System.Runtime.Caching库是.NET 4.0引入的缓存库,用于提高应用程序性能。它提供了一组API,用于在内存中存储、检索和管理缓存对象,并包括一些高级功能,如回调和过期策略等。在.NET 7.0中,System.Runtime.Caching库进行了进一步改进和优化,可用于实现不同级别的缓存管理。下面我们对其进行详细介绍和分类。

以下是System.Runtime.Caching库按照不同的功能和用途进行分类,并附有源代码剖析:

System.Runtime.Caching库的适用场景

System.Runtime.Caching库适用于需要在应用程序中实现内存缓存的场景。以下是一些常见的使用场景:

  • 数据库查询结果的缓存:在数据库查询时,如果查询结果重复使用的概率较高,可以使用MemoryCache类将结果缓存到内存中,减少对数据库的访问次数,提高性能。
  • 频繁读取的配置信息:在应用程序中,一些配置信息需要频繁读取,这些配置信息可以通过MemoryCache类缓存起来,提高应用程序的响应速度。
  • 网络请求响应的缓存:在网络请求中,如果某个请求的响应结果较为稳定,可以使用MemoryCache类将响应结果缓存到内存中,提高响应速度和吞吐量。
  • 预先加载静态资源:在Web应用程序中,某些静态资源(如CSS、JS等)需要在应用程序启动时预先加载,这些资源可以使用MemoryCache类进行缓存,提高页面渲染速度。
  • 业务逻辑计算结果的缓存:在某些业务逻辑中,需要频繁进行计算,如果计算结果稳定,可以使用MemoryCache类缓存计算结果,提高计算速度。

System.Runtime.Caching库的优缺点

System.Runtime.Caching是Microsoft提供的内存缓存方案,封装了一组用于管理缓存的API。它使用MemoryCache类来实现内存缓存,可以用于单个应用程序域或分布式系统中。以下是System.Runtime.Caching的优缺点:

优点:

  • 高性能:System.Runtime.Caching使用内存缓存,相比于其他持久化缓存方案,具有更高的读写速度和更低的响应延迟。
  • 简单易用:System.Runtime.Caching提供了易于使用的API,可以方便地创建、访问和管理内存缓存,适用于各种.NET应用程序。
  • 可扩展性:System.Runtime.Caching支持多种缓存项过期策略、缓存项优先级和回收策略,可以根据特定需求进行自定义。
  • 高可靠性:System.Runtime.Caching支持缓存项压缩、内存监视和回收机制等功能,可以有效提高缓存的可靠性和稳定性。

缺点:

  • 有容量上限:System.Runtime.Caching使用内存缓存,所以缓存的容量受到硬件资源的限制。对于大型的数据集合,需要考虑使用其他缓存方式或增加硬件资源。
  • 无法持久化:System.Runtime.Caching只是一个内存缓存方案,不支持将缓存项持久化到磁盘或其他介质中。如果需要实现持久化缓存,需要使用其他缓存方案。
  • 可能存在并发访问问题:System.Runtime.Caching默认情况下是线程安全的,但是在高并发环境下,仍然可能存在竞争条件和死锁等问题。需要注意并发访问限制和异常处理。

System.Runtime.Caching库API介绍

System.Runtime.Caching提供了一组用于管理缓存的API,主要包括以下类型:

  • MemoryCache类:实现了一个内存缓存,可以用于单个应用程序域或分布式系统中。MemoryCache支持多种缓存项过期策略、缓存项优先级和回收策略,可以根据具体需求进行自定义。常用方法包括Add、Get、Set和Remove等。
  • CacheItem类:表示缓存中的一个项。CacheItem包含缓存键、缓存值和缓存过期策略等属性,可以通过构造函数创建缓存项,也可以通过MemoryCache类的方法管理缓存项。
  • CacheItemPolicy类:表示一个缓存项的过期策略。CacheItemPolicy包含过期时间、优先级、回收处理和缓存移除回调等属性,可以通过构造函数创建缓存项策略,并设置给MemoryCache或CacheItem对象。
  • CacheEntryRemovedArguments类:表示缓存项移除时的参数。CacheEntryRemovedArguments包含了缓存项的键、值、移除原因和移除通知等属性,可以在缓存项移除时进行处理。
  • CacheEntryUpdateArguments类:表示缓存项更新时的参数。CacheEntryUpdateArguments包含了旧的缓存项的键、值和更新通知等属性,可以在缓存项更新时进行处理。
  • CacheEntryChangeMonitor类:表示一个监视缓存项变化的对象。CacheEntryChangeMonitor支持多种变化监视器,例如文件监视器、键依赖监视器和SqlDependency监视器等。

MemoryCache类

MemoryCache类是System.Runtime.Caching库中的核心类,它表示一个内存中的缓存集合。MemoryCache类是一个线程安全的、可扩展的、基于键值对的缓存系统。MemoryCache类提供了以下一些方法:

  • Add(string key, object value, CacheItemPolicy policy):向缓存中添加一个具有指定键和值的缓存项,并使用指定的策略对象指定该缓存项的过期和依赖项信息。
  • Contains(string key):返回一个值,指示指定键是否存在于缓存中。
  • Get(string key):获取指定键的缓存项。
  • Remove(string key):从缓存中移除指定键的缓存项。
  • GetCount():获取当前缓存中的项数。
  • Dispose():释放MemoryCache对象占用的资源。

源代码剖析:

[DefaultMember("Item")]
    public class MemoryCache : ObjectCache, IEnumerable, IDisposable
    {
        public MemoryCache(string name, NameValueCollection config = null);
        public MemoryCache(string name, NameValueCollection config, bool ignoreConfigSection);

        public override object this[string key] { get; set; }

        public static MemoryCache Default { get; }
        public long PhysicalMemoryLimit { get; }
        public override string Name { get; }
        public long CacheMemoryLimit { get; }
        public TimeSpan PollingInterval { get; }
        public override DefaultCacheCapabilities DefaultCacheCapabilities { get; }
			  // 添加缓存项
        public override bool Add(CacheItem item, CacheItemPolicy policy);
        public override object AddOrGetExisting(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null);
        public override CacheItem AddOrGetExisting(CacheItem item, CacheItemPolicy policy);
        public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null);
        public override bool Contains(string key, string regionName = null);
        public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(IEnumerable keys, string regionName = null);
        public void Dispose();
      
       // 获取缓存项
        public override object Get(string key, string regionName = null);
        public override CacheItem GetCacheItem(string key, string regionName = null);
        public override long GetCount(string regionName = null);
        public long GetLastSize(string regionName = null);
        public override IDictionary GetValues(IEnumerable keys, string regionName = null);
        public override object Remove(string key, string regionName = null);
      
       // 移除缓存项  
       public object Remove(string key, CacheEntryRemovedReason reason, string regionName = null);
        public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null);
        public override void Set(CacheItem item, CacheItemPolicy policy);
        public override void Set(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null);
        public long Trim(int percent);
      
        // 遍历缓存
        protected override IEnumerator GetEnumerator();
    }

CacheItem和CacheItemPolicy类

CacheItem表示一个缓存项,包括键、值、过期时间等属性。CacheItemPolicy则表示一个策略对象,用于指定缓存项的一些属性,如过期时间、回收策略、依赖项等。

源代码剖析:

public class CacheItem
{
  public CacheItem(string key);
  public CacheItem(string key, object value);
  public CacheItem(string key, object value, string regionName);

  public string Key { get; set; }
	public object Value { get; set; }
	public string RegionName { get; set; }
}

public class CacheItemPolicy
{
        public CacheItemPolicy();
  
        public DateTimeOffset AbsoluteExpiration { get; set; }
        public Collection ChangeMonitors { get; }
        public CacheItemPriority Priority { get; set; }
        public CacheEntryRemovedCallback RemovedCallback { get; set; }
        public TimeSpan SlidingExpiration { get; set; }
        public CacheEntryUpdateCallback UpdateCallback { get; set; }
  }

CacheEntryChangeMonitor类

CacheEntryChangeMonitor类提供了监视缓存项更改的功能,以便在发生更改时执行回调函数或其他操作。

源代码剖析:

public abstract class CacheEntryChangeMonitor : ChangeMonitor
    {
        protected CacheEntryChangeMonitor();

        public abstract ReadOnlyCollection CacheKeys { get; }
        public abstract DateTimeOffset LastModified { get; }
        public abstract string RegionName { get; }
    }

缓存对象的管理方式

过期策略

过期策略用于确定何时从缓存中删除对象,以防止缓存过多的对象导致内存泄漏或性能降低。System.Runtime.Caching库中提供了三种基本的过期策略:绝对时间、相对时间和空闲时间。可以通过CacheItemPolicy类中的AbsoluteExpiration、SlidingExpiration属性指定缓存项的过期策略。

源代码剖析:

public class CacheItemPolicy
{
    // 设置过期时间(绝对时间)
    public DateTimeOffset? AbsoluteExpiration { get; set; }

    // 设置过期时间(相对时间)
    public TimeSpan? SlidingExpiration { get; set; }
}

依赖关系

依赖关系用于使缓存项具有基于文件、目录、键或其他对象的依赖关系。当这些依赖项更改时,缓存中的项将自动无效。在System.Runtime.Caching库中,可以通过以下类实现依赖关系的管理:

  • CacheDependency类:表示一个基于文件或目录的依赖项。
  • ChangeMonitor类:表示一个监视缓存项的变化的类,包括CacheDependency、FileChangeMonitor、SqlChangeMonitor等。

源代码剖析:

public class CacheDependency : IDisposable
{
    public CacheDependency(string filename);
    public CacheDependency(string[] filenames);
    public virtual string GetUniqueID();
    public virtual void NotifyDependencyChanged(object sender, EventArgs e);
}

public abstract class ChangeMonitor : IDisposable
{
    // 标识缓存项是否已过期
    public virtual bool HasChanged { get; }
}

回调函数

回调函数用于在缓存项过期或被删除时执行指定的回调函数。在System.Runtime.Caching库中,可以通过CacheItemPolicy类中的RemovedCallback属性指定当缓存项过期或被删除时要执行的回调函数。

源代码剖析:

public class CacheItemPolicy
{
    // 设置缓存项被删除时的回调函数
    public int RemovedCallback { get; set; }
}

高级功能

缓存统计信息

缓存统计信息提供了缓存对象的统计数据,如当前缓存项数目、命中率等。在System.Runtime.Caching库中,可以通过MemoryCacheStatistics类获取缓存统计信息。

源代码剖析:

public sealed class MemoryCacheStatistics
{
    public int Count { get; }
    public long Hits { get; }
    public double HitRatio { get; }
    public long Misses { get; }
    public double MissRatio { get; }
}

高级回收策略

高级回收策略提供了自定义的回收策略,以更精细地控制缓存对象的生命周期。在System.Runtime.Caching库中,可以通过以下类实现高级回收策略的管理:

  • ICachePolicyManager接口:表示一个可自定义的缓存策略管理器。
  • CacheMemoryPressureMonitor类:表示一个监视系统内存压力的对象。
  • BackgroundMemoryMonitor类:表示一个后台线程,用于检测系统内存压力并根据指定的缓存策略来删除缓存项。

源代码剖析:

public interface ICachePolicyManager
{
    CacheItemPolicy GetItemPolicy(string key, object value);
}

public sealed class CacheMemoryPressureMonitor : IDisposable
{
    // 监视系统内存压力,并设置相应的缓存策略
}

public sealed class BackgroundMemoryMonitor : IDisposable
{
    public BackgroundMemoryMonitor(ICachePolicyManager policyManager);
    // 监视系统内存压力,并根据缓存策略来删除缓存项
}

缓存区域

缓存区域允许将缓存项分配到不同的区域,以便更好地管理和组织缓存项。在System.Runtime.Caching库中,可以通过CacheArea类实现缓存区域的管理。

源代码剖析:

public class CacheArea : IDisposable
{
    public CacheArea(string name);
    public string Name { get; }
    public void Dispose();
    public object Get(string key);
    public bool Contains(string key);
    public void Add(string key, object value, CacheItemPolicy policy);
    public void Remove(string key);
}

完整的示例代码

以下是一个使用System.Runtime.Caching命名空间的示例代码,展示了如何使用MemoryCache类来创建缓存并添加、获取和删除缓存项:

using System;
using System.Runtime.Caching;

namespace MemoryCacheDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个内存缓存对象
            MemoryCache cache = MemoryCache.Default;

            // 添加一个缓存项
            cache.Add("key1", "value1", DateTimeOffset.UtcNow.AddMinutes(30));

            // 获取缓存项的值
            Object value = cache.Get("key1");
            if (value != null)
            {
                Console.WriteLine("获取缓存项:{0}", value);
            }

            // 删除缓存项
            cache.Remove("key1");

            // 再次尝试获取已被删除的缓存项
            value = cache.Get("key1");
            if (value == null)
            {
                Console.WriteLine("获取失败,缓存项已被删除");
            }

            // 设置缓存项的属性
            CacheItemPolicy policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(30);
            cache.Set("key2", "value2", policy);

            Console.ReadKey();
        }
    }
}

在这个例子中,我们首先使用MemoryCache.Default静态属性来获取默认的内存缓存对象。然后,我们使用Add方法向缓存中添加一个项,Get方法从缓存中获取一个项,Remove方法从缓存中删除一个项,以及Set方法设置缓存项的属性。注意,我们使用CacheItemPolicy类来指定缓存项的过期时间和其他选项。

以上是System.Runtime.Caching库按照不同的功能和用途进行分类,并提供相应的源代码剖析。根据实际需求,可以选择适当的API和功能进行组合使用,以达到最佳的性能和效果。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论