能否将缓存的同步查询结果用于多个异步查询方法?
当然可以实现
核心思路
先确保Foo()的缓存逻辑正确,然后在各个异步方法中直接复用该方法返回的内存数据,执行Linq操作后包装为异步任务返回即可。如果数据库查询本身是IO密集型操作,建议将Foo()改为异步方法,更符合.NET异步编程规范。
实现示例
1. 同步版Foo()(缓存+数据库查询)
private readonly IMemoryCache _cache; private readonly YourDbContext _dbContext; public YourService(IMemoryCache cache, YourDbContext dbContext) { _cache = cache; _dbContext = dbContext; } // 主查询方法:优先从缓存取,无缓存则查库并存缓存 public List<MyCustomClass> Foo() { const string cacheKey = "MyCustomClass_AllData"; return _cache.GetOrCreate(cacheKey, entry => { // 设置缓存策略,比如滑动过期30分钟 entry.SlidingExpiration = TimeSpan.FromMinutes(30); // 从数据库同步查询数据 return _dbContext.MyCustomClasses.ToList(); }); }
2. 基于同步Foo()的异步业务方法
如果仅需对内存数据做Linq处理,直接用Task.FromResult包装结果即可返回异步任务:
// 示例A:过滤数据 public Task<List<MyCustomClass>> MyAmazingMethodA(int targetId) { var allData = Foo(); var filteredData = allData.Where(item => item.Id == targetId).ToList(); return Task.FromResult(filteredData); } // 示例Z:分组+转换 public Task<List<GroupedResultDto>> MyAmazingMethodZ() { var allData = Foo(); var groupedData = allData.GroupBy(item => item.Category) .Select(g => new GroupedResultDto { Category = g.Key, ItemCount = g.Count() }) .ToList(); return Task.FromResult(groupedData); }
3. 更推荐的异步版FooAsync()
因为数据库查询是IO操作,异步实现能避免阻塞线程,优化资源利用率:
public async Task<List<MyCustomClass>> FooAsync() { const string cacheKey = "MyCustomClass_AllData"; return await _cache.GetOrCreateAsync(cacheKey, async entry => { entry.SlidingExpiration = TimeSpan.FromMinutes(30); // 异步查询数据库 return await _dbContext.MyCustomClasses.ToListAsync(); }); }
对应的异步业务方法直接用await调用即可:
public async Task<List<MyCustomClass>> MyAmazingMethodA(int targetId) { var allData = await FooAsync(); return allData.Where(item => item.Id == targetId).ToList(); } // 如果业务中还有其他异步操作,直接结合使用 public async Task<List<DetailedDto>> MyAmazingMethodZ() { var allData = await FooAsync(); var grouped = allData.GroupBy(item => item.Category); var result = new List<DetailedDto>(); foreach (var group in grouped) { // 调用其他异步服务处理分组数据 var detailedDto = await _yourOtherService.ProcessGroupAsync(group); result.Add(detailedDto); } return result; }
注意事项
IMemoryCache本身是线程安全的,GetOrCreate/GetOrCreateAsync会自动处理并发请求,避免重复执行数据库查询。- 根据业务需求调整缓存策略(比如绝对过期、滑动过期),确保数据时效性。
- 如果缓存数据需要更新,记得主动移除对应缓存键,保证下次查询能获取最新数据。
内容的提问来源于stack exchange,提问作者CodeIT
相关产品推荐
相关产品推荐

