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

发布于 2024-11-07 02:45:15 字数 807 浏览 1 评论 0原文

长期倾听者 - 第一次来电者。我希望得到一些建议。我一直在阅读有关 .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;
        }
    }
}

除了过期(我不希望它过期)之外,我不知道使用内置缓存有什么好处。

也许更复杂的缓存场景有一些好处,但不适用于我 - 或者也许我只是错过了一些东西(这不是第一次)。

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

Long time listener - first time caller. I am hoping to get some advice. I have been reading about caching in .net - both with System.Web.Caching and System.Runtime.Caching. I am wondering what additional benefits I can get vs simply creating a static variable with locking. My current (simple minded) caching method is like this:

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;
        }
    }
}

Other than expiration (and I wouldn't want this to expire) I am at a loss to see what the benefit of using the built in caching are.

Maybe there are benefits for more complex caching scenarios that don't apply to me - or maybe I am just missing something (would not be the first time).

So, what is the advantage of using cache if I want a cache that never expires? Doesn't static variables do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无名指的心愿 2024-11-14 02:45:15

首先,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防止呼叫者认为他们可以添加到此列表中。

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

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

这种方法将使您能够对应该对所有类别执行操作的类进行单元测试,并完全控制测试哪些“类别”,并且不需要数据库调用。

First of all, Xaqron makes a good point that what you're talking about probably doesn't qualify as caching. It's really just a lazily-loaded globally-accessible variable. That's fine: as a practical programmer, there's no point bending over backward to implement full-on caching where it's not really beneficial. If you're going to use this approach, though, you might as well be Lazy and let .NET 4 do the heavy lifting:

private static Lazy<IEnumerable<Category>> _allCategories
    = new Lazy<IEnumerable<Category>>(() => /* Db call to populate */);

public static IEnumerable<Category> AllCategories 
{ 
    get { return _allCategories.Value; } 
}

I took the liberty of changing the type to IEnumerable<Category> to prevent callers from thinking they can add to this list.

That said, any time you're accessing a public static member, you're missing out on a lot of flexibility that Object-Oriented Programming has to offer. I'd personally recommend that you:

  1. Rename the class to CategoryRepository (or something like that),
  2. Make this class implement an ICategoryRepository interface, with a GetAllCategories() method on the interface, and
  3. Have this interface be constructor-injected into any classes that need it.

This approach will make it possible for you to unit test classes that are supposed to do things with all the categories, with full control over which "categories" are tested, and without the need for a database call.

层林尽染 2024-11-14 02:45:15

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

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

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

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

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

System.Runtime.Caching and System.Web.Caching have automatic expiration control, that can be based on file-changes, SQL Server DB changes, and you can implement your own "changes provider". You can even create dependecies between cache entries.

See this link to know more about the System.Caching namespace:

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

All of the features I have mentioned are documented in the link.

Using static variables, would require manual control of expiration, and you would have to use file system watchers and others that are provided in the caching namespace.

若水微香 2024-11-14 02:45:15

除了过期(我不希望它过期)...

如果您不关心生命周期,则名称不再缓存

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

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

If you don't care about the life-time the name is not caching anymore.

Still using Application (your case) and Session object are best practices for storing application level and session level data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文