私は次のコードを使用していますが、以下のコードでは競合状態が発生しないようです。または、競合状態の可能性はまだありますか?
List<Document> listFromCache = Cache[dataCacheName] as List<Document>;
if (listFromCache != null)
{
//do something with listFromCache. **IS IT POSSIBLE** that listFromCache is
//NULL here
}
else
{
List<Document> list = ABC.DataLayer.GetDocuments();
Cache.Insert(dataCacheName, list, null, DateTime.Now.AddMinutes(5),
System.Web.Caching.Cache.NoSlidingExpiration);
}
更新: クリスはこの問題の解決を手伝ってくれましたが、他の人にとって非常に役立つ詳細を共有したいと思いました.
競合状態を完全に回避するために、真の部分にチェックを追加する必要がありました。そうしないと、他の誰かがキャッシュでそれをクリアした場合 (アイテムを削除するのではなく、 my if が TRUE と評価された後、キャッシュ内のオブジェクトをリストします。したがって、listFromCache オブジェクトの if の真の部分にはデータがありません。
元のコードのこの微妙な RACE 状態を克服するには、以下のコードのように、実際の部分で listFromCache を再確認してから、キャッシュに最新のデータを再入力する必要があります。
また、Chris が言ったように、誰かが Cache.Remove メソッドを呼び出してキャッシュからアイテムを「削除」した場合、listFromCache は影響を受けません。 listFromCache' はまだそれへの参照を持っています (これについては、Chris の回答投稿の下のコメントで詳しく説明しました)。
List<Document> listFromCache = Cache[dataCacheName] as List<Document>;
if (listFromCache != null)
{
//OVERCOME A SUBTLE RACE CONDITION BY IF BELOW
if( listFromCache == null || listFromCache.Count == 0)
{
List<Document> list = ABC.DataLayer.GetDocuments();
Cache.Insert(dataCacheName, list, null, DateTime.Now.AddMinutes(5),
System.Web.Caching.Cache.NoSlidingExpiration);
}
//NOW I AM SURE MY listFromCache contains true data
//do something with listFromCache. **IS IT POSSIBLE** that listFromCache is
//NULL here
}
else
{
List<Document> list = ABC.DataLayer.GetDocuments();
Cache.Insert(dataCacheName, list, null, DateTime.Now.AddMinutes(5),
System.Web.Caching.Cache.NoSlidingExpiration);
}