自从长时间操作开始以来,确定ASP.Net中的数据缓存是否具有挑战性

时间:2013-01-01 20:47:45

标签: c# asp.net caching

我将一个List插入到ASP.Net中的数据缓存中,如下面的示例代码所示。我使用C#作为编程语言。

我无法找到解决以下问题的方法:

  1. 启动可能持续.1秒到20秒的长数据库操作。
  2. 在此操作结束时,我需要确定自长时间操作开始以来(即操作正在进行时)是否已从数据库重新插入或刷新了名为“dSummary”的缓存
  3. 我用来插入缓存项的代码如下:

          List<Doc> ds = GetDocSummary();
       System.Web.HttpContext.Current.Cache.Insert("dSummary", ds, null, 
               DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration);
    

    更新1:

    在得到这么多回复之后,我认为一种可能的万无一失的方法是将一个guid字符串与List对象一起存储在Cache中。然后我可以简单地比较长操作之前和之后存储在Cache中的对象的guid字符串属性。如果它们相同,则Cache [“dSummary”]尚未重新插入,否则它已被重新插入。 所以我需要使用以下扩展类的'Doc'类。

    public class DocX : Doc
     { 
              public UniQueIdentifier { get;set; }
              public DocX ( Doc doc, string unqiueIdentifier)
                 {
                      this.Doc = doc;
                      this.UniqueIdentifier = unqiueIdentifier;
    
                }
     }
    

    然后我会使用以下代码插入缓存:

           List<Doc> ds = GetDocSummary();
           System.Web.HttpContext.Current.Cache.Insert("dSummary",new DocX( ds,  
                    new Guid.Newguid().ToString() ), null, 
               DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration);
    

3 个答案:

答案 0 :(得分:2)

我会在您添加或更新包含您修改它的时间戳的dSummary时添加另一个Cache属性。

您可以在长时间运行的开始记录原始值,并将其与结束时缓存中的当前值进行比较;如果值不同,则更新数据。

答案 1 :(得分:1)

假设有两个或更多线程想要获取文档摘要,我想你不希望所有这些都计算摘要(正如你所说的那样,它是一个长时间运行的计算密集型操作)。在这种情况下,我采用以下解决方案:

//declare lock object for implementing critical section
private static object docSummaryLock = new object();

//this is the body of GetDocSummary method
List<Doc> ds = (List<Doc>) System.Web.HttpContext.Current.Cache.Get("dSummary");
if (ds != null) return ds;
//summary not found in cache, computing the doc summary occurs in critical section
lock (docSummaryLock)
{
    //there is possibility that another thread waited for obtaining the lock and the summary may be already in cache
    ds = (List<Doc>) System.Web.HttpContext.Current.Cache.Get("dSummary");
    if (ds != null) return ds;

    //compute the summary
    ds = GetDocSummary();
    System.Web.HttpContext.Current.Cache.Insert("dSummary", summaries, null, 
    DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration);
    return ds;
}

答案 2 :(得分:1)

在开始操作GetDocSummary()之前,您可以从缓存中获取当前值,并在本地变量中存储该值(或来自此值的哈希值,如果内存可能存在问题)。 操作完成后,在将数据添加到缓存之前,将局部变量与当前缓存的值进行比较。

根据评论添加一些样本,使用Tuple

var cacheEntry = new Tuple<List<Doc>, DateTime>(ds, DateTime.Now);

执行GetDocSummary()后,从缓存中获取您的条目,并查看日期是否在开始和结束此操作之间。