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

2023-09-02 01:54:46 作者:烟花巷陌*

很长一段时间听众 - 第一次来电。我希望能得到一些建议。我一直在阅读有关缓存在.net中 - 都与System.Web.Caching和System.Runtime.Caching。我想知道什么额外的好处,我可以得到VS简单的创建一个静态变量与锁定。我现在的(头脑简单)高速缓存方法是这样的:

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?

推荐答案

首先,Xaqron使得一个好点的是什么你在谈论可能没有资格作为缓存。这真的只是一个懒洋洋地加载全局访问的变量。这很好:作为一个实际的程序员,没有一点年轻气盛实现全高速缓存上它不是真的有益。如果你打算使用这种方法,不过,你还不如延迟,让.NET 4做繁重的:

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

我把改变类型的自由的IEnumerable&LT;类别&GT; 来prevent主叫方认为他们可以添加到这个列表

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:

重命名类CategoryRepository(或类似的东西), 请该类实施 ICategoryRepository 接口,使​​用 GetAllCategories()法的界面上,和 有这个接口是构造注入到需要它的任何类。 Rename the class to CategoryRepository (or something like that), Make this class implement an ICategoryRepository interface, with a GetAllCategories() method on the interface, and 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.