Кеширование не выполняется после изменения файла FileDependency - PullRequest
1 голос
/ 21 марта 2011

Я использую библиотеку кэширования библиотеки Microsoft EnterPrise (версия 5) с FileDependency.

В классе, который я хочу кэшировать, у меня есть статическое свойство, которое либо возвращает элемент из кэша, либоиначе создайте новый класс и добавьте его в кеш.

Это изначально хорошо работает, и класс создается один раз, и с тех пор возвращается кэшированная копия.Однако, как только файл зависимостей изменяется, кэшированный элемент никогда не возвращается.

Я собрал пример программы ниже, чтобы проиллюстрировать проблему.

Выходные данные:

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;
        }
    }

}

}

1 Ответ

1 голос
/ 21 марта 2011

Ваша проблема в том, что вы используете статический FileDependency. Это приводит к тому, что LastUpdateTime FileDependency никогда не обновляется, что, в свою очередь, приводит к тому, что все элементы, добавленные в кэш, отображаются как просроченные (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)) { }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...