控制台应用程序内存缓存

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 秒...

查看缓存

不,不在缓存中

正在添加到缓存中...

它在测试缓存中!

按下一个键...