Asp.Net 重新进入页面时清除缓存

Asp.Net Cache is cleared when reentering the page

我有一个 asp.net 函数用作报告的数据源。当我第一次运行函数时,我缓存了数据集,发现缓存创建成功,因为缓存计数为1。但是,当我再次进入该函数时,我无法获取缓存内容。缓存计数为零。似乎由于某种原因清除了缓存。重新进入页面时如何找出缓存计数为零的原因以及如何使缓存工作?这是我的代码:

//using System.Web.Caching;
using System.Runtime.Caching;

namespace Sustainability.BusinessObject.Client
{
    public class ReportManager
    {
        protected static MemoryCache CACHE = new MemoryCache("MySQLDataProvider_Cache");

        public static DataSet KPISummaryReport(int companyID, int fromYear, int fromMonth, int toYear, int toMonth, string locationIDs, bool hideIfNoValue, string lang)
        {
            HttpResponseMessage result = null;            
            DataSet ds = null; 
            try
            {
                string cacheKey = "kpi_" + companyID + "_" + fromYear + "_" + fromMonth + "_" + toYear + "_" + toMonth + "_" + locationIDs;

                Logger.Log(string.Format("Cache count of reentering the code {0}", CACHE.GetCount()));
                ds = CACHE.Get(cacheKey) as DataSet;

                if (ds != null)
                {
                    return ds;
                }
                else
                {
                    ds = Util.GetData(_sustainabilityServiceURL, requestUri, out result);
                    var policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now.AddMinutes(60d) };
                    CACHE.Add(cacheKey, ds, policy);

                    DataSet ds1 = CACHE.Get(cacheKey) as DataSet;

                    if (ds1 != null)
                    {
                        Logger.Log("Create Cache Succesfully");
                    }
                    else
                    {
                        Logger.Log("Create Cache Failed");
                    }

                    Logger.Log(string.Format("Cache count after create cache {0}",CACHE.GetCount()));
                }
         }
   }

检查您用于缓存的数据库,我的第一个猜测是实际上没有存储任何内容。

使用 IoC,正确的设置类似于向服务添加分布式缓存

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = _config["SQLDataProvider_Cache"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

您可以使用两种类型的缓存策略:

  • (DateTimeOffSet) CacheItemPolicy.AbsoluteExpiration 在初始设置的固定时间后到期

  • (DateTimeOffSet) CacheItemPolicy.SlidingExpiration 在上次访问的固定时间后过期

通常你会想使用 SlidingExpiration 一个,但是当你定义绝对时,注册会

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    IApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        var encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetAbsoluteExpiration(TimeSpan.FromHours(1));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

存储库本身不应包含静态成员(或仅包含记录器)。为这个存储库添加一个接口将改进测试和模拟功能,以及使用 IoC

传递它的默认方式
public class ReportRepository : IReportRepository
{
    private readonly IAppCache _cache;
    private readonly ILogger _logger;
    private SomeService _service;

    public string ServiceUrl { get; set; }
    public string RequestUri { get; set; }
 
    public ReportRepository(IAppCache appCache, ILogger<ShowDatabase> logger, SomeService service)
    {
        _service = service;
        _logger = logger;
        _cache = appCache;
    }
 
    public async Task<List<Show>> GetShows()
    {    
        var cacheKey = "kpi_{companyID}_{fromYear}_{fromMonth}_{toYear}_{toMonth}_{locationIDs}";
        Func<Task<List<DataSet>>> reportFactory = () => PopulateReportCache();
        //if you do it in DistributedCacheEntryOptions you do not need to set it here
        var absoluteExpiration = DateTimeOffset.Now.AddHours(1);
        var result = await _cache.GetOrAddAsync(cacheKey, reportFactory, absoluteExpiration);
        return result;
    }
  
    private async Task<List<DataSet>> PopulateReportCache()
    {
        List<DataSet> reports = await _service.GetData(ServiceUrl, RequestUri, out result);
        _logger.LogInformation($"Loaded {reports.Count} report(s)");
        return reports.ToList(); //I would have guessed it returns out parameter result ...
    }
}

有关更多信息,请查看 Cache in-memory in ASP.NET Core


编辑

在 .net 4.5 中使用 LazyCache

var cache = new CachingService();
var cachedResults = cache.GetOrAdd(key, () => SetMethod());

使用sql 服务器、mysql、postgres 等,然后只需实现ObjectCache 并将其传递给缓存服务的构造函数。这是一个 guide,其中还列出了一些更常见的,例如 Redis。它默认为 20 分钟滑动过期,您可以通过更改策略来设置它。