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 分钟滑动过期,您可以通过更改策略来设置它。
我有一个 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 分钟滑动过期,您可以通过更改策略来设置它。