【问题标题】:Caching fails after FileDependency file changesFileDependency 文件更改后缓存失败
【发布时间】:2011-03-21 13:54:58
【问题描述】:

我正在使用带有 FileDependency 的 Microsoft Enterprise Library Caching 库(版本 5)。

在我想要缓存的类上,我有一个静态属性,它要么从缓存中返回项目,要么创建一个新类并将其添加到缓存中。

这最初运行良好,并且类被创建一次,从那时起,缓存的副本被返回。但是,一旦依赖文件发生更改,缓存项就永远不会返回。

我在下面整理了一个示例程序来说明这个问题。

这个的输出是

999 cached , 1 uncached
999 cached , 1001 uncached

我希望结果是

 999 cached , 1 uncached
1998 cached , 2 uncached

看起来该对象已添加回缓存,但随后由于过期而立即被删除。

有什么想法吗?

using System;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

namespace TestCache
{
  static class Program
  {
    [STAThread]
    static void Main()
    {
        Cache.Create();

        for (int i = 0; i < 1000; i++)
            TestClass.Current.DummyMethod();
        Console.WriteLine(String.Format("{0} cached , {1} uncached", TestClass.CachedItems, TestClass.UncachedItems));

        System.IO.File.AppendAllText(Cache.dependencyFileName, "Test");

        for (int i = 0; i < 1000; i++)
            TestClass.Current.DummyMethod();           
        Console.WriteLine(String.Format("{0} cached , {1} uncached", TestClass.CachedItems, TestClass.UncachedItems));

        Console.ReadLine();
    }
}

 public class Cache
{
    public static CacheManager cacheManager = null;
    public static string dependencyFileName;
    public static FileDependency objFileDependency;

    public static void Create()
    {
        var builder = new ConfigurationSourceBuilder();

        builder.ConfigureCaching()
               .ForCacheManagerNamed("TestCache")
               .UseAsDefaultCache()
               .StoreInMemory();

        var configSource = new DictionaryConfigurationSource();
        builder.UpdateConfigurationWithReplace(configSource);
        EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);

        cacheManager = (CacheManager)EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>("TestCache");

        dependencyFileName = "testCache.xml";
        if (!System.IO.File.Exists(dependencyFileName))
            using (System.IO.File.Create(dependencyFileName)) { }

        objFileDependency = new FileDependency(dependencyFileName);
    }
}

public class TestClass
{

    public static int CachedItems =0;
    public static int UncachedItems = 0;

    public void DummyMethod()
    {
    }

    public static TestClass Current
    {
        get
        {
            TestClass current = (Cache.cacheManager.GetData("Test") as TestClass);
            if (current != null)
                CachedItems++;
            else
            {
                UncachedItems++;
                current = new TestClass();
                Cache.cacheManager.Add("Test", current, CacheItemPriority.Normal, null, new ICacheItemExpiration[] { Cache.objFileDependency });
            }
            return current;
        }
    }

}

}

【问题讨论】:

    标签: c# caching enterprise-library


    【解决方案1】:

    您的问题是您使用的是静态FileDependency。这导致 FileDependency 的 LastUpdateTime 永远不会被更新,进而导致添加到缓存中的所有项目都显示为过期 (HasExpired() == true)。即使您将项目添加到缓存中,因为它们已过期,您也永远无法检索它们。

    解决方案是对缓存的所有添加使用新的FileDependency 对象。最简单的更改是用属性替换 objFileDependency 字段。使用您现有的名称和方法,代码如下所示:

    public class Cache
    {
        public static CacheManager cacheManager = null;
        public static readonly string dependencyFileName = "testCache.xml";            
    
        public static FileDependency objFileDependency
        {
            get
            {
                return new FileDependency(dependencyFileName);
            }
        }
    
        public static void Create()
        {
            var builder = new ConfigurationSourceBuilder();
    
            builder.ConfigureCaching()
                   .ForCacheManagerNamed("TestCache")
                   .UseAsDefaultCache()
                   .StoreInMemory();
    
            var configSource = new DictionaryConfigurationSource();
            builder.UpdateConfigurationWithReplace(configSource);
            EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
    
            cacheManager = (CacheManager)EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>("TestCache");
    
            if (!System.IO.File.Exists(dependencyFileName))
                using (System.IO.File.Create(dependencyFileName)) { }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-22
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 2020-12-13
      • 2013-01-03
      相关资源
      最近更新 更多