ASP.NET缓存和文件依赖性

Fly*_*wat 3 asp.net caching file-dependancy

我希望在触摸特定文件时回收ASP.NET缓存项,但以下代码不起作用:

                       HttpContext.Current.Cache.Insert(
                            "Key",
                            SomeObject,
                            new CacheDependency(Server.MapPath("SomeFile.txt")),
                            DateTime.MaxValue,
                            TimeSpan.Zero,
                            CacheItemPriority.High,
                            null);
Run Code Online (Sandbox Code Playgroud)

我在点击缓存时似乎没有检查"SomeFile.txt",修改它不会导致此项无效.

我究竟做错了什么?

Fly*_*wat 5

问题解决了:

这是一个独特而有趣的问题,所以我将把这里的原因和解决方案记录为答案,供未来的搜索者使用.

我在问题中遗漏的一点是,这个缓存插入是在实现单例模式的服务类中发生的.

简而言之:

public class Service 
{
        private static readonly Service _Instance = new Service();
        static Service () { }
        private Service () { }

        public static Service Instance
        {
            get { return _Instance; }
        }

        // The expensive data that this service exposes      
        private someObject _data = null;

        public someObject Data
        {
            get
            {
                 if (_data == null)
                     loadData();
                 return _data;
            }
        }


        private void loadData()
        {
            _data = GetFromCache();
            if (_data == null)
            {
                 // Get the data from our datasource
                 _data = ExpensiveDataSourceGet();

                 // Insert into Cache
                 HttpContext.Current.Cache.Insert(etc);
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

对某些人来说可能是显而易见的,但这里的罪魁祸首是单身模式中的延迟加载.我陷入困境,认为缓存没有失效,我忘记了只要工作进程存活,单例的状态就会持续存在.

Cache.Insert有一个重载,它允许你为删除缓存项时指定一个事件处理程序,我的第一个测试是创建一个虚拟处理程序并在其中设置一个断点.一旦我看到缓存被清除,我意识到"_data"没有被重置为null,因此对单例的下一个请求加载了延迟加载的值.

从某种意义上说,我是双重缓存,虽然单例缓存非常短暂,但足够长,令人讨厌.

解决方案?

 HttpContext.Current.Cache.Insert(
     "Key",
      SomeObject,
      new CacheDependency(Server.MapPath("SomeFile.txt")),
      DateTime.MaxValue,
      TimeSpan.Zero,
      CacheItemPriority.High,
      delegate(string key, object value, CacheItemRemovedReason reason)
      {
          _data = null;
      }
 );
Run Code Online (Sandbox Code Playgroud)

清除缓存后,还必须清除单例内的状态...问题已解决.

在这里学到的经验?不要把状态放在单身人士身上.