LazyCache源码解析:Lazy<T>与IMemoryCache的完美结合

LazyCache源码解析:Lazy 与IMemoryCache的完美结合

【免费下载链接】LazyCache An easy to use thread safe in-memory caching service with a simple developer friendly API for c# 【免费下载链接】LazyCache 项目地址: https://gitcode.com/gh_mirrors/la/LazyCache

LazyCache是一个简单易用的线程安全内存缓存服务,为C#开发者提供友好的API接口。它巧妙地结合了Lazy 延迟加载机制与IMemoryCache缓存功能,在保证高性能的同时简化了缓存逻辑的实现。本文将深入剖析LazyCache的核心设计理念与实现细节,帮助开发者理解其内部工作原理。

核心架构:Lazy 与IMemoryCache的融合

LazyCache的核心优势在于将Lazy 的延迟初始化特性与IMemoryCache的缓存管理能力无缝结合。这种组合不仅减少了不必要的计算开销,还确保了多线程环境下的安全性。

在LazyCache的实现中,LazyCache/CachingService.cs是核心类,它通过GetValueFromLazy<T>GetValueFromAsyncLazy<T>方法处理缓存项的获取逻辑:

protected virtual T GetValueFromLazy<T>(object item, out bool valueHasChangedType)
{
    valueHasChangedType = false;
    switch (item)
    {
        case Lazy<T> lazy:
            return lazy.Value;
        case AsyncLazy<T> asyncLazy:
            valueHasChangedType = true;
            return asyncLazy.GetAwaiter().GetResult();
        default:
            valueHasChangedType = true;
            return (T)item;
    }
}

这段代码展示了LazyCache如何处理不同类型的缓存项,特别是Lazy 和AsyncLazy 类型,实现了延迟加载与缓存的完美结合。

缓存提供器:基于IMemoryCache的实现

LazyCache使用IMemoryCache作为底层缓存存储,通过LazyCache/Providers/MemoryCacheProvider.cs封装了缓存的基本操作:

internal readonly IMemoryCache cache;
public MemoryCacheProvider(IMemoryCache cache)
{
    this.cache = cache ?? throw new ArgumentNullException(nameof(cache));
}

这种设计使得LazyCache可以轻松集成到ASP.NET Core应用中,通过依赖注入配置缓存服务。在LazyCache.AspNetCore/LazyCacheServiceCollectionExtensions.cs中可以看到服务注册的实现:

services.TryAdd(ServiceDescriptor.Singleton<IMemoryCache, MemoryCache>());

核心API:GetOrAdd方法解析

LazyCache提供的GetOrAdd方法是其最核心的API之一,它实现了"如果缓存存在则获取,不存在则添加"的逻辑,同时利用Lazy 确保了只有一个线程会执行创建逻辑。

LazyCache/IAppCache.cs中定义了GetOrAdd方法的接口:

T GetOrAdd<T>(string key, Func<ICacheEntry, T> addItemFactory);
Task<T> GetOrAddAsync<T>(string key, Func<ICacheEntry, Task<T>> addItemFactory);

而在LazyCache/CachingService.cs中的实现则展示了如何结合Lazy 和IMemoryCache:

public virtual T GetOrAdd<T>(string key, Func<ICacheEntry, T> addItemFactory)
{
    return GetOrAdd(key, addItemFactory, null);
}

实际的缓存项创建逻辑使用了Lazy 来包装:

new Lazy<T>(() =>
{
    var entry = cacheProvider.CreateEntry(key);
    // ... 设置缓存策略
    var result = addItemFactory(entry);
    entry.SetValue(result);
    return result;
})

这种设计确保了即使在高并发场景下,昂贵的创建操作也只会执行一次。

异步支持:AsyncLazy 的实现

LazyCache对异步操作提供了一流的支持,通过LazyCache/AsyncLazy.cs实现了异步版本的延迟加载:

public class AsyncLazy<T> : Lazy<Task<T>>

AsyncLazy 类继承自Lazy<Task >,结合了延迟初始化和异步编程模型。在CachingService中, GetOrAddAsync方法使用AsyncLazy 来处理异步缓存项的创建:

new AsyncLazy<T>(async () =>
{
    var entry = cacheProvider.CreateEntry(key);
    // ... 设置缓存策略
    var result = await addItemFactory(entry).ConfigureAwait(false);
    entry.SetValue(result);
    return result;
})

实际应用示例

Console.Net461/Program.cs中可以看到LazyCache的基本用法:

var item = cache.GetOrAdd("Program.Main.Person", () => Tuple.Create("Joe Blogs", DateTime.UtcNow));

而在CacheDatabaseQueriesApiSample/Controllers/DbTimeController.cs中展示了如何缓存数据库查询结果:

var cachedDatabaseTime = cache.GetOrAdd(cacheKey, actionThatWeWantToCache);

这些示例展示了LazyCache简洁易用的API设计,开发者无需关心复杂的缓存逻辑,只需专注于业务代码。

总结:LazyCache的优势与适用场景

LazyCache通过将Lazy 的延迟加载与IMemoryCache的缓存管理相结合,提供了一个高性能、线程安全且易于使用的缓存解决方案。其主要优势包括:

  1. 简化缓存逻辑:通过GetOrAdd方法将缓存检查和添加逻辑合并,减少样板代码
  2. 线程安全:利用Lazy 确保并发环境下昂贵操作只执行一次
  3. 异步支持:原生支持异步操作,不会阻塞线程
  4. 与ASP.NET Core集成:提供了LazyCache.AspNetCore项目,可无缝集成到ASP.NET Core应用中

LazyCache特别适合需要频繁访问相同数据且数据计算或获取成本较高的场景,如数据库查询、API调用结果缓存等。通过使用LazyCache,开发者可以轻松提升应用性能,同时保持代码的简洁性和可维护性。

【免费下载链接】LazyCache An easy to use thread safe in-memory caching service with a simple developer friendly API for c# 【免费下载链接】LazyCache 项目地址: https://gitcode.com/gh_mirrors/la/LazyCache

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值