2

以下のサンプルコードに示すように、ASP.Netのデータキャッシュにリストを挿入しています。私はプログラミング言語としてC#を使用しています。

次の問題の解決策を見つけることができません:

  1. .1秒から20秒続く可能性のある長いデータベース操作が開始されます。
  2. この操作の最後に、長い操作が開始されてから(つまり、操作の進行中に)、「dSummary」という名前のキャッシュがデータベースから再挿入または更新されたかどうかを確認する必要があります。

キャッシュアイテムを挿入するために使用するコードは次のとおりです。

      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オブジェクトと一緒にキャッシュに格納することだと思います。次に、長い操作の前後にキャッシュに格納されているオブジェクトの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);
4

3 に答える 3

2

変更したタイムスタンプを含むdSummaryを追加または更新するときに、別のCacheプロパティを追加するだけです。

長時間実行操作の開始時に元の値を記録し、最後にキャッシュ内の現在の値と比較できます。値が異なる場合は、データが更新されました。

于 2013-01-01T20:51:58.737 に答える
1

ドキュメントの要約を取得したいスレッドが2つ以上あるとすると、それらすべてに要約を計算させたくないと思います(計算集約型の長時間実行操作であるとおっしゃっていました)。そのような場合、私は次の解決策を採用します。

//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;
}
于 2013-01-01T21:03:17.717 に答える
1

操作を開始する前にGetDocSummary()、キャッシュから現在の値を取得し、その値(またはメモリが問題になる可能性がある場合はこの値からのハッシュ)をローカル変数に格納できます。操作が終了した後、データをキャッシュに追加する前に、ローカル変数を現在のキャッシュ値と比較します。

コメントに基づいて、Tuple:を使用してサンプルを追加します。

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

を実行した後GetDocSummary()、キャッシュからエントリを取得し、日付がこの操作の開始と終了の間にあるかどうかを確認します。

于 2013-01-01T21:12:33.870 に答える