我最近在阅读ASP.NET的缓存策略时已经阅读了很多内容,而我从未提到过使用静态字段作为缓存存储的方法。这是一种不好的做法,如果是这样,为什么?以下是我通常如何使用它的示例:
public static Class Repository {
private static object _lockObject = new object();
private static List<Products> _products = null;
public static void GetProducts() {
if (_products != null) { return _products; }
lock(_lockObject) {
_products = DAL.LoadProducts()
}
return products;
}
}
我更喜欢这种模式的原因是,System.Runtime.Caching.MemoryCache是因为它不使用序列化,因此可以扩展到大对象;我已经成功地使用它来从整个数据库表中缓存非常大的对象集合,然后我使用LINQ查询而不是使用SQL查询数据库,从而大大提高了性能。这种模式在以下场景中的许多项目中都很有用:
由于我发现这种模式非常有用,我很好奇为什么关于这个主题的各种书籍和教程甚至都没有真正讨论它作为一种选择。
答案 0 :(得分:1)
鉴于您对MemoryCache的理解是错误的,并且在MemoryCache中存储内容比使用静态内容更少的代码,我不明白为什么您会坚持使用容易出错,漏洞的模式,并且更难以使用...
无论如何,有时使用静态来缓存某些东西是合适的。但是,一般来说,您应该初始化静态并且在过程的生命周期中永远不会更改静态。一旦你开始玩东西,你就会开始痛苦。
答案 1 :(得分:1)
这是一个旧线程,但是遇到一些未填充的数据缓存时,有两个线程执行相同工作的问题有一个简单的解决方案。该技术称为双重锁定。
public static class Repository<T>
{
private static readonly object LockSemaphore = new object();
private static T _dataYouWantCached;
public static void ReadData()
{
if (_dataYouWantCached != null)
{
return _dataYouWantCached;
}
lock (LockSemaphore)
{
//This second check will prevent the "next" thread from requerying the same data that
//the first thread populated.
//This is the "Double Lock"
if (_dataYouWantCached != null)
return _dataYouWantCached;
_dataYouWantCached = SomeStaticDataAccess.LoadData();
return _dataYouWantCached;
}
}
}