代码之家  ›  专栏  ›  技术社区  ›  FlySwat

ASP.NET缓存和文件依赖性

  •  3
  • FlySwat  · 技术社区  · 17 年前

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

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

    当我点击缓存时,“SomeFile.txt”似乎没有被选中,修改它不会导致该项无效。

    我做错了什么?

    5 回复  |  直到 6 年前
        1
  •  5
  •   Community Mohan Dere    6 年前

    解决的问题:

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

    简言之:

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

    Insert有一个重载,允许您为移除缓存项时指定事件处理程序,我的第一个测试是创建一个虚拟处理程序并在其中设置断点。当我看到缓存正在被清除时,我意识到“\u data”没有被重置为null,因此下一个对singleton的请求加载了lazy-loaded值。

    从某种意义上说,我是双缓存,虽然单例缓存的寿命很短,但足够长,令人讨厌。

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

    当缓存被清除时,单例中的状态也必须被清除…问题解决了。

    从这里吸取的教训?不要把国家放在一个人身上。

        2
  •  1
  •   Chris Symons    17 年前

    ASP.NET是否在对CacheDependency中指定的文件具有适当权限的帐户下运行?如果不是,那么这可能是CacheDependency无法正常工作的原因之一。

        3
  •  0
  •   Mark Brackett    17 年前

    我认为您需要指定一个路径:

    var d = new CacheDependency(Server.MapPath("SomeFile.txt"));
    

    预先准备 ~\App_Data 根据需要。

        4
  •  0
  •   womp    17 年前

    我觉得你的代码很好。然而,任何事情都有可能超出这个片段。

    • 你是不是有机会在每一封回信上都插上?

    • 尝试将缓存依赖项设置为类字段,并在每次回发时检查它。修改中间的文件,看看它是否注册为“已更改”。例如。:

      public partial class _Default : System.Web.UI.Page
      {
         CacheDependency dep;
      
      protected void Page_Load(object sender, EventArgs e)
      {
          if (!IsPostBack)
          {
              dep = new CacheDependency(Server.MapPath("SomeFile.txt"));
              HttpContext.Current.Cache.Insert(
                          "Key",
                          new Object(),
                          dep,
                          DateTime.MaxValue,
                              TimeSpan.Zero, CacheItemPriority.High, null);
          }
      
      
          if (dep.HasChanged)
              Response.Write("changed!");
          else
              Response.Write("no change :(");   }}
      
        5
  •  0
  •   Rex M    17 年前