繁体   English   中英

重新进入页面时,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 ...
    }
}

有关更多信息,请检查ASP.NET Core中的“缓存内存”


编辑

在.net 4.5中使用LazyCache

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

要使用sql server,mysql,postgres等,只需实现ObjectCache并将其传递给缓存服务的构造函数即可。 这是一份指南 ,其中还列出了一些更常见的指南 ,例如Redis。 默认为20分钟滑动到期时间,您可以通过更改策略进行设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM