长时间听众 - 第一次来电。我希望得到一些建议。我一直在阅读.net中的缓存 - 包括System.Web.Caching和System.Runtime.Caching。我想知道我可以获得什么额外的好处与简单地创建一个带锁定的静态变量。我目前的(简单的)缓存方法是这样的:
public class Cache
{
private static List<Category> _allCategories;
private static readonly object _lockObject = new object();
public static List<Category> AllCategories
{
get
{
lock (_lockObject)
{
if (_allCategories == null)
{
_allCategories = //DB CALL TO POPULATE
}
}
return _allCategories;
}
}
}
除了过期(我不希望它过期),我很遗憾看到使用内置缓存的好处是什么。
对于不适用于我的更复杂的缓存方案可能有好处 - 或者我可能只是缺少某些东西(这不是第一次)。
那么,如果我想要一个永不过期的缓存,那么使用缓存有什么好处?静态变量不这样做吗?
答案 0 :(得分:20)
System.Runtime.Caching和System.Web.Caching具有自动过期控制,可以基于文件更改, SQL Server数据库更改< / strong>,您可以实现自己的“更改提供程序”。您甚至可以在缓存条目之间创建依赖关系。
请参阅此链接以了解有关System.Caching命名空间的更多信息:
http://msdn.microsoft.com/en-us/library/system.runtime.caching.aspx
我提到的所有功能都记录在链接中。
使用静态变量需要手动控制过期时间,您必须使用文件系统观察者和缓存命名空间中提供的其他人。
答案 1 :(得分:20)
首先,Xaqron提出了一个很好的观点,即您所谈论的内容可能不符合缓存条件。它实际上只是一个懒惰的全局可访问变量。这很好:作为一个实用的程序员,没有必要向后弯曲以实现全面的缓存,而这并不是真正有益的。但是,如果您打算使用这种方法,那么您可能会Lazy
并让.NET 4解决这个问题:
private static Lazy<IEnumerable<Category>> _allCategories
= new Lazy<IEnumerable<Category>>(() => /* Db call to populate */);
public static IEnumerable<Category> AllCategories
{
get { return _allCategories.Value; }
}
我冒昧地将类型更改为IEnumerable<Category>
,以防止来电者认为他们可以添加到此列表中。
也就是说,无论何时访问公共静态成员,都会错失面向对象编程所提供的大量灵活性。我个人建议你:
ICategoryRepository
接口,并在接口上使用GetAllCategories()
方法,这种方法可以使您可以对所有类别的事物进行单元测试,完全控制测试哪些“类别”,而无需数据库调用。
答案 2 :(得分:3)
Other than expiration (and I wouldn't want this to expire) ...
如果您不关心终身名称,则不再是caching
。
仍然使用Application
(您的情况)和Session
对象是存储应用程序级别和会话级别数据的最佳做法。