You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于异步生成器创建内存缓存的方法及CS0149错误解决

错误修复方案

错误原因

CS0149报错的核心是GetAsync方法的第二个参数类型定义错误:
你当前使用的Task<Func<T>>代表「一个已启动的Task实例,其返回值为同步委托Func<T>」,直接执行generatorasync()相当于把Task对象当作方法调用,不符合C#语法规范。

修正方法

将参数类型改为Func<Task<T>>,代表「一个返回异步任务的委托,调用后会执行你定义的EF Core查询等异步逻辑」。
修正后的完整代码如下:

using Microsoft.Extensions.Caching.Memory;
using System;
using System.Threading.Tasks;

public sealed class CacheManager
{
    readonly IMemoryCache memoryCache;
    public CacheManager(IMemoryCache memoryCache)
    { 
        this.memoryCache = memoryCache;
    }

    public async Task<T> GetAsync<T>(string key, Func<Task<T>> generatorAsync)
    {
        var cacheEntry = await memoryCache.GetOrCreateAsync<T>(key, async entry =>
        {
            entry.SlidingExpiration = TimeSpan.FromMinutes(15);
            // 可选:增加绝对过期时间,避免高频访问导致缓存永久不更新
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(2);
            return await generatorAsync();
        });
        return cacheEntry;
    }
}

调用示例(结合EF Core查询):

// 服务中注入CacheManager和你的DbContext后调用
var products = await _cacheManager.GetAsync("product_all", async () =>
{
    return await _context.Products.AsNoTracking().ToListAsync();
});

异步内存缓存实现最佳实践

  • 双过期策略配置:滑动过期基础上新增绝对过期,避免热点数据因持续访问长期不更新,导致数据不一致
  • 空值缓存处理:如果数据源返回空结果,可设置较短的过期时间缓存空值,避免缓存穿透,大量无效请求直接访问数据库
  • 缓存键规范管理:不同业务场景的缓存键增加统一前缀,比如用户相关缓存加user_前缀,商品相关加product_前缀,避免键冲突,也方便后续批量清理同类型缓存
  • 异常捕获:在异步生成委托中增加异常处理逻辑,避免数据源查询失败时导致整个缓存获取流程崩溃,同时不要缓存异常结果
  • 热点key防击穿:对于访问量极高的缓存key,可增加本地锁逻辑,避免缓存失效瞬间大量请求同时查询数据库,造成数据库压力陡增

内容的提问来源于stack exchange,提问作者Andrus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:57:03