控制台应用程序内存缓存
Console Application Memory Cache
我已经研究过,联系过朋友,但仍然无法正常工作。甚至 Caching in a console application 真的没有回答这个问题。
我有一个计划任务,在接下来的 12 小时内,每小时 运行 使用去年的数据作为参考,运行此应用程序一次。
当然,去年的数据不会改变,这是使用缓存的完美案例,特别是因为查询需要 90 到 110 秒才能运行,具体取决于服务器的繁忙程度。
using System.Runtime.Caching;
private static ObjectCache o_Cache = MemoryCache.Default;
private static IEnumerable<SWFSalesModel> GetLastYearsSalesData(ObjectCache o_Cache, string cacheKey) {
IEnumerable<SWFSalesModel> arrLastYearsData = o_Cache.GetCacheItem(cacheKey) as IEnumerable<SWFSalesModel>;
if (arrLastYearsData == null) {
Console.WriteLine("Look in the cache 2");
arrLastYearsData = (IEnumerable<SWFSalesModel>)o_Cache.Get(cacheKey);
}
if (arrLastYearsData == null) {
Console.WriteLine("Look in the cache 3");
arrLastYearsData = (IEnumerable<SWFSalesModel>)o_Cache[cacheKey];
}
if (arrLastYearsData != null) {
return arrLastYearsData;
} else {
Console.WriteLine("nope, not in the cache");
arrLastYearsData = GetLastYearSales(); ;
CacheItemPolicy policy = new CacheItemPolicy();
Console.WriteLine("Adding to the cache...");
policy.AbsoluteExpiration = DateTimeOffset.Now.AddHours(12.0);
o_Cache.Add(cacheKey, arrLastYearsData, policy);
IEnumerable<SWFSalesModel> arrTest = (IEnumerable<SWFSalesModel>)o_Cache[cacheKey];
if (arrTest != null) {
/* This works 100% of the time */
Console.WriteLine("it's in test cache!");
} else {
Console.WriteLine("nope, nada in test cache");
}
return arrLastYearsData;
}
}
然后在程序中调用:
/* Get Last Years Sales Data */
string cacheKey = DateTime.Today.ToString("MM/dd/yyyy");
IEnumerable<SWFSalesModel> arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
我也试过它在函数中引用内存缓存:
private static IEnumerable<SWFSalesModel> GetLastYearsSalesData(string cacheKey) {
ObjectCache o_Cache = MemoryCache.Default;
....
}
有些事情我显然不明白,非常感谢任何人在这方面的帮助!
好的,让我们看几点:
- 为什么要从 MemoryCache to ObjectCache 投射?在这段代码中,我看不出有任何理由这样做;
- 为什么要测试 3 种方法来获取缓存? GetCacheItem will return a CacheItem object, so your code will always fail there (at the
as
cast). Looking your piece of code, I think that just using the Get 方法就够了(如果缓存不存在,它会 return null);
- 你的时间政策没问题。如果您的计划恰好在同一政策到期日,您将永远不会刷新缓存。
所以,我用 15 秒过期策略对您的代码进行了测试,只需更改时间,您就可以看到它有效。请仔细查看您的计划时间并将其与您的代码进行比较。
private static MemoryCache o_Cache = MemoryCache.Default;
static void Main(string[] args)
{
string cacheKey = DateTime.Today.ToString("MM/dd/yyyy");
IEnumerable<SWFSalesModel> arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
Console.WriteLine();
Console.WriteLine("Waiting 10 seconds...");
Console.WriteLine();
System.Threading.Thread.Sleep(10000);
arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
Console.WriteLine();
Console.WriteLine("Waiting 10 seconds...");
Console.WriteLine();
System.Threading.Thread.Sleep(10000);
arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
Console.WriteLine();
Console.WriteLine("Press a key...");
Console.ReadKey();
}
private static IEnumerable<SWFSalesModel> GetLastYearsSalesData(MemoryCache o_Cache, string cacheKey)
{
Console.WriteLine("Looking at the cache");
var arrLastYearsData = (IEnumerable<SWFSalesModel>)o_Cache.Get(cacheKey);
if (arrLastYearsData != null)
{
return arrLastYearsData;
}
else
{
Console.WriteLine("nope, not in the cache");
arrLastYearsData = GetLastYearSales(); ;
CacheItemPolicy policy = new CacheItemPolicy();
Console.WriteLine("Adding to the cache...");
policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(15);
o_Cache.Add(cacheKey, arrLastYearsData, policy);
IEnumerable<SWFSalesModel> arrTest = (IEnumerable<SWFSalesModel>)o_Cache[cacheKey];
if (arrTest != null)
{
Console.WriteLine("it's in test cache!");
}
else
{
Console.WriteLine("nope, nada in test cache");
}
return arrLastYearsData;
}
}
// just a test
private static IEnumerable<SWFSalesModel> GetLastYearSales()
{
List<SWFSalesModel> result = new List<SWFSalesModel>();
result.Add(new SWFSalesModel());
result.Add(new SWFSalesModel());
result.Add(new SWFSalesModel());
return result;
}
这是控制台结果:
查看缓存
不,不在缓存中
正在添加到缓存中...
它在测试缓存中!
等待 10 秒...
查看缓存
等待 10 秒...
查看缓存
不,不在缓存中
正在添加到缓存中...
它在测试缓存中!
按下一个键...
我已经研究过,联系过朋友,但仍然无法正常工作。甚至 Caching in a console application 真的没有回答这个问题。
我有一个计划任务,在接下来的 12 小时内,每小时 运行 使用去年的数据作为参考,运行此应用程序一次。
当然,去年的数据不会改变,这是使用缓存的完美案例,特别是因为查询需要 90 到 110 秒才能运行,具体取决于服务器的繁忙程度。
using System.Runtime.Caching;
private static ObjectCache o_Cache = MemoryCache.Default;
private static IEnumerable<SWFSalesModel> GetLastYearsSalesData(ObjectCache o_Cache, string cacheKey) {
IEnumerable<SWFSalesModel> arrLastYearsData = o_Cache.GetCacheItem(cacheKey) as IEnumerable<SWFSalesModel>;
if (arrLastYearsData == null) {
Console.WriteLine("Look in the cache 2");
arrLastYearsData = (IEnumerable<SWFSalesModel>)o_Cache.Get(cacheKey);
}
if (arrLastYearsData == null) {
Console.WriteLine("Look in the cache 3");
arrLastYearsData = (IEnumerable<SWFSalesModel>)o_Cache[cacheKey];
}
if (arrLastYearsData != null) {
return arrLastYearsData;
} else {
Console.WriteLine("nope, not in the cache");
arrLastYearsData = GetLastYearSales(); ;
CacheItemPolicy policy = new CacheItemPolicy();
Console.WriteLine("Adding to the cache...");
policy.AbsoluteExpiration = DateTimeOffset.Now.AddHours(12.0);
o_Cache.Add(cacheKey, arrLastYearsData, policy);
IEnumerable<SWFSalesModel> arrTest = (IEnumerable<SWFSalesModel>)o_Cache[cacheKey];
if (arrTest != null) {
/* This works 100% of the time */
Console.WriteLine("it's in test cache!");
} else {
Console.WriteLine("nope, nada in test cache");
}
return arrLastYearsData;
}
}
然后在程序中调用:
/* Get Last Years Sales Data */
string cacheKey = DateTime.Today.ToString("MM/dd/yyyy");
IEnumerable<SWFSalesModel> arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
我也试过它在函数中引用内存缓存:
private static IEnumerable<SWFSalesModel> GetLastYearsSalesData(string cacheKey) {
ObjectCache o_Cache = MemoryCache.Default;
....
}
有些事情我显然不明白,非常感谢任何人在这方面的帮助!
好的,让我们看几点:
- 为什么要从 MemoryCache to ObjectCache 投射?在这段代码中,我看不出有任何理由这样做;
- 为什么要测试 3 种方法来获取缓存? GetCacheItem will return a CacheItem object, so your code will always fail there (at the
as
cast). Looking your piece of code, I think that just using the Get 方法就够了(如果缓存不存在,它会 return null); - 你的时间政策没问题。如果您的计划恰好在同一政策到期日,您将永远不会刷新缓存。
所以,我用 15 秒过期策略对您的代码进行了测试,只需更改时间,您就可以看到它有效。请仔细查看您的计划时间并将其与您的代码进行比较。
private static MemoryCache o_Cache = MemoryCache.Default;
static void Main(string[] args)
{
string cacheKey = DateTime.Today.ToString("MM/dd/yyyy");
IEnumerable<SWFSalesModel> arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
Console.WriteLine();
Console.WriteLine("Waiting 10 seconds...");
Console.WriteLine();
System.Threading.Thread.Sleep(10000);
arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
Console.WriteLine();
Console.WriteLine("Waiting 10 seconds...");
Console.WriteLine();
System.Threading.Thread.Sleep(10000);
arrLastYearSales = GetLastYearsSalesData(o_Cache, cacheKey);
Console.WriteLine();
Console.WriteLine("Press a key...");
Console.ReadKey();
}
private static IEnumerable<SWFSalesModel> GetLastYearsSalesData(MemoryCache o_Cache, string cacheKey)
{
Console.WriteLine("Looking at the cache");
var arrLastYearsData = (IEnumerable<SWFSalesModel>)o_Cache.Get(cacheKey);
if (arrLastYearsData != null)
{
return arrLastYearsData;
}
else
{
Console.WriteLine("nope, not in the cache");
arrLastYearsData = GetLastYearSales(); ;
CacheItemPolicy policy = new CacheItemPolicy();
Console.WriteLine("Adding to the cache...");
policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(15);
o_Cache.Add(cacheKey, arrLastYearsData, policy);
IEnumerable<SWFSalesModel> arrTest = (IEnumerable<SWFSalesModel>)o_Cache[cacheKey];
if (arrTest != null)
{
Console.WriteLine("it's in test cache!");
}
else
{
Console.WriteLine("nope, nada in test cache");
}
return arrLastYearsData;
}
}
// just a test
private static IEnumerable<SWFSalesModel> GetLastYearSales()
{
List<SWFSalesModel> result = new List<SWFSalesModel>();
result.Add(new SWFSalesModel());
result.Add(new SWFSalesModel());
result.Add(new SWFSalesModel());
return result;
}
这是控制台结果:
查看缓存
不,不在缓存中
正在添加到缓存中...
它在测试缓存中!
等待 10 秒...
查看缓存
等待 10 秒...
查看缓存
不,不在缓存中
正在添加到缓存中...
它在测试缓存中!
按下一个键...