C# 停止双重加载缓存
给定从数据库加载所有可用语言的代码(仅用作示例):C# 停止双重加载缓存,c#,asp.net,caching,locking,C#,Asp.net,Caching,Locking,给定从数据库加载所有可用语言的代码(仅用作示例): // ///所有语言词典 /// 私有静态字典GetLanguagesDictionary() { const string cacheIndex=Settings.CachePrefix+“LanguagesDictionary”; var context=HttpContext.Current; if(context.Cache[cacheIndex]==null) { var dict=新字典(); 使用(var db=new DBCo
//
///所有语言词典
///
私有静态字典GetLanguagesDictionary()
{
const string cacheIndex=Settings.CachePrefix+“LanguagesDictionary”;
var context=HttpContext.Current;
if(context.Cache[cacheIndex]==null)
{
var dict=新字典();
使用(var db=new DBContext())
{
var q=数据库语言;
foreach(q中的var rec)
{
dict.Add(rec.ID,新语言(rec));
}
}
context.Cache.Add(cacheIndex,dict,null,Cache.noabsoluteexption,Cache.NoSlidingExpiration,CacheItemPriority.Normal,null);
}
return(Dictionary)context.Cache[cacheIndex];
}
如果将记录加载到缓存中的代码需要一段时间才能完成,并且出现另一个页面请求,则会引发异常并导致一些问题
修改上述代码以使其在这种情况下安全的最佳方法是什么?您可以使用Lazy
您必须使用
锁
同步缓存的写入和创建,如下所示:
///
/// for locking synhronize
///
private static readonly object syncLock = new object();
/// <summary>
/// Dictionary of all languages
/// </summary>
private static Dictionary<int, Language> GetLanguagesDictionary()
{
const string cacheIndex = Settings.CachePrefix + "LanguagesDictionary";
var context = HttpContext.Current;
if (context.Cache[cacheIndex] == null)
{
lock (syncLock)
{
if (context.Cache[cacheIndex] == null)
{
var dict = new Dictionary<int, Language>();
using (var db = new DBContext())
{
var q = db.Languages;
foreach (var rec in q)
{
dict.Add(rec.ID, new Language(rec));
}
}
context.Cache.Add(cacheIndex, dict, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}
}
return (Dictionary<int, Language>)context.Cache[cacheIndex];
}
///
///用于锁定同步
///
私有静态只读对象syncLock=新对象();
///
///所有语言词典
///
私有静态字典GetLanguagesDictionary()
{
const string cacheIndex=Settings.CachePrefix+“LanguagesDictionary”;
var context=HttpContext.Current;
if(context.Cache[cacheIndex]==null)
{
锁定(同步锁定)
{
if(context.Cache[cacheIndex]==null)
{
var dict=新字典();
使用(var db=new DBContext())
{
var q=数据库语言;
foreach(q中的var rec)
{
dict.Add(rec.ID,新语言(rec));
}
}
context.Cache.Add(cacheIndex,dict,null,Cache.noabsoluteexption,Cache.NoSlidingExpiration,CacheItemPriority.Normal,null);
}
}
}
return(Dictionary)context.Cache[cacheIndex];
}
@downvoter您能解释一下-1的原因吗?我想这就是我想要的!当我读到更多关于它和另一个的内容时,我会接受的answers@TomGullen是的,这就是解决方案。。。当您从非同步化代码访问静态数据时,请始终使用锁定…我以前没有使用过lazy,但我提供的代码是由设计延迟加载的。使用lazy有什么好处吗?@TomGullen它的.Value
方法是线程安全的。访问值
的第一个线程开始操作,所有其他线程(访问值
)等待值
被删除available@TomGullen这样,您就不需要context.Cache或其他空检查。只需创建字典,填写并返回即可。如果你把GetLanguage
公之于众,你可以在任何地方访问它@顺便说一句,不要忘记,在您当前的代码中,您有许多副本,因为您将其存储在HttpContext.current中
static Lazy<Dictionary<int, Language>> GetLanguage =
new Lazy<Dictionary<int, Language>>(() => GetLanguagesDictionary(), true);
private static Dictionary<int, Language> GetLanguagesDictionary()
{
var dict = new Dictionary<int, Language>();
using (var db = new DBContext())
{
var q = db.Languages;
foreach (var rec in q)
{
dict.Add(rec.ID, new Language(rec));
}
}
return dict;
}
public static Lazy<Dictionary<int, Language>> GetLanguages =
new Lazy<Dictionary<int, Language>>(() => GetLanguagesDictionary(), true);
///
/// for locking synhronize
///
private static readonly object syncLock = new object();
/// <summary>
/// Dictionary of all languages
/// </summary>
private static Dictionary<int, Language> GetLanguagesDictionary()
{
const string cacheIndex = Settings.CachePrefix + "LanguagesDictionary";
var context = HttpContext.Current;
if (context.Cache[cacheIndex] == null)
{
lock (syncLock)
{
if (context.Cache[cacheIndex] == null)
{
var dict = new Dictionary<int, Language>();
using (var db = new DBContext())
{
var q = db.Languages;
foreach (var rec in q)
{
dict.Add(rec.ID, new Language(rec));
}
}
context.Cache.Add(cacheIndex, dict, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}
}
return (Dictionary<int, Language>)context.Cache[cacheIndex];
}