为什么使用System.Runtime.Caching或System.Web.Caching Vs静态变量?

长时间听众 – 第一次来电。 我希望得到一些建议。 我一直在阅读.net中的缓存 – 包括System.Web.Caching和System.Runtime.Caching。 我想知道我可以获得什么额外的好处与简单地创建一个带锁定的静态变量。 我目前的(简单的)缓存方法是这样的:

public class Cache { private static List _allCategories; private static readonly object _lockObject = new object(); public static List AllCategories { get { lock (_lockObject) { if (_allCategories == null) { _allCategories = //DB CALL TO POPULATE } } return _allCategories; } } } 

除了到期(我不希望它到期)我不知道使用内置缓存的好处是什么。

也许对于不适用于我的更复杂的缓存方案有好处 – 或者我可能只是缺少一些东西(这不是第一次)。

那么,如果我想要一个永不过期的缓存,使用缓存有什么好处? 静态变量不这样做吗?

首先,Xaqron提出了一个很好的观点,即你所谈论的内容可能不具备缓存的条件。 它实际上只是一个懒惰的全局可访问变量。 这很好:作为一个实用的程序员,没有必要向后弯曲以实现全面的缓存,而这并不是真正有益的。 但是,如果你打算使用这种方法,你可能也是Lazy ,让.NET 4做得很重:

 private static Lazy> _allCategories = new Lazy>(() => /* Db call to populate */); public static IEnumerable AllCategories { get { return _allCategories.Value; } } 

我冒昧地将类型更改为IEnumerable以防止调用者认为他们可以添加到此列表中。

也就是说,无论何时访问公共静态成员,您都会错失面向对象编程所提供的大量灵活性。 我个人建议你:

  1. 将类重命名为CategoryRepository(或类似的东西),
  2. 使该类实现一个ICategoryRepository接口,在接口上使用GetAllCategories()方法,并且
  3. 将此接口构造符注入任何需要它的类。

这种方法使您可以对应该对所有类别执行操作的unit testing类进行unit testing,并完全控制测试哪些“类别”,而无需数据库调用。

System.Runtime.Caching和System.Web.Caching具有自动过期控制 ,可以基于文件更改SQL Server数据库更改 ,并且您可以实现自己的“更改提供程序”。 您甚至可以在缓存条目之间创建依赖关系。

请参阅此链接以了解有关System.Caching命名空间的更多信息:

http://msdn.microsoft.com/en-us/library/system.runtime.caching.aspx

我提到的所有function都记录在链接中。

使用静态变量需要手动控制过期,并且您必须使用文件系统观察器和缓存命名空间中提供的其他人。

Other than expiration (and I wouldn't want this to expire) ...

如果你不关心生命,那么这个名字就不再caching了。

仍然使用Application (您的案例)和Session对象是存储应用程序级别和会话级别数据的最佳实践。