简体   繁体   English

自长时间的操作开始以来就很难确定ASP.Net中的数据缓存是否已更改

[英]Challenging to determine if Cache for data has been changed in ASP.Net since a long operation began

I am inserting a List into data cache in ASP.Net as shown in sample code below. 我将列表插入ASP.Net中的数据缓存中,如下面的示例代码所示。 I am using C# as the programming language. 我正在使用C#作为编程语言。

I am not able to find a solution to following problem: 我无法找到以下问题的解决方案:

  1. A long database operation which could last from .1 s to 20 s is started. 开始了可能持续0.1秒到20秒的长时间数据库操作。
  2. At the end of this operation, I need to determine if the Cache by the name of 'dSummary' has been re-inserted or refreshed from database since the long operation began (ie while the operation was in progress). 在此操作结束时,我需要确定自长时间操作开始以来(即,在操作正在进行时)是否已从数据库中重新插入或刷新了名为“ dSummary”的Cache。

The code I use to insert cache item is as below: 我用来插入缓存项的代码如下:

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

UPDATE 1: 更新1:

After getting so many replies, I think a possible foolproof approach would be to store a guid string along with the List object in Cache. 在收到如此多的答复之后,我认为一种可能的万无一失的方法是将Guid字符串与List对象一起存储在Cache中。 Then I could simply compare the guid string property of the object stored in Cache before and after the long operation. 然后,我可以简单地比较长操作前后存储在Cache中的对象的guid字符串属性。 If they are the same then Cache["dSummary"] has not been re-inserted, else it has been re-inserted. 如果它们相同,则尚未重新插入Cache [“ dSummary”],否则已重新插入。 So I would need to use the following extended class of 'Doc' class. 因此,我需要使用以下“ Doc”类的扩展类。

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

            }
 }

I would then insert into cache using following code: 然后,我将使用以下代码插入缓存:

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

I would just add another Cache property at the time that you add or update dSummary that contains the timestamp that you modified it. 我只是在添加或更新包含修改后的时间戳的dSummary时添加另一个Cache属性。

You can record the original value at the start of the long-running operation and compare it to the current value in the cache at the end; 您可以在长时间运行的操作开始时记录原始值,然后在结束时将其与缓存中的当前值进行比较。 if the values are different, the data was updated. 如果值不同,则数据已更新。

Suppose there are two or more threads that want to obtain docs summary, I guess you don't want all of them to compute the summary (as you said it is a long running operation that is compute intensive). 假设有两个或多个线程想要获取文档摘要,我想您不希望它们全部都计算摘要(因为您说这是一个长时间运行的操作,需要大量计算)。 In such case I go with following solution: 在这种情况下,我采用以下解决方案:

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

Before starting the operation GetDocSummary() you could get the current value from the cache and store that value (or a Hash from this value, if memory might be an issue) in a local variable. 在开始操作GetDocSummary()您可以从缓存中获取当前值,并将该值(如果内存可能是问题,则从该值中获取哈希值)存储在局部变量中。 After the operation is finished, before adding the data to the cache, compare the local variable with the current cached value. 操作完成后,在将数据添加到缓存之前,请将本地变量与当前缓存的值进行比较。

Adding some sample, based on the comments, using a Tuple : 根据注释,使用Tuple添加一些示例:

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

After executing GetDocSummary() , get your entry from the cache and see if the date falls between starting and ending this operation. 执行GetDocSummary() ,从缓存中获取条目,并查看日期是否介于此操作的开始和结束之间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM