在ASP.NET中使用静态字段来缓存大型对象是不好的做法吗?

本文关键字:对象 大型 缓存 NET ASP 字段 静态 | 更新日期: 2023-09-27 18:15:36

我最近读了很多关于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 . cache . memorycache这个模式是因为它不使用序列化,因此可以扩展到大型对象;我已经成功地使用它从整个数据库表中缓存非常大的对象集合,然后我使用LINQ而不是用SQL查询DB进行查询,从而获得了巨大的性能提升。此模式在以下场景中为我的许多项目提供了很好的服务:
  1. 我想缓存从存储中检索成本很高的大型数据集
  2. 数据将被缓存数小时或数天,不需要担心是否过期。
  3. 频繁使用的数据,但通常针对特定请求进行唯一过滤或转换。
  4. 数据量在主机服务器的内存容量内。

既然我发现这个模式如此有用,我很好奇为什么关于这个主题的各种书籍和教程甚至没有真正地将它作为一个选项来讨论。

在ASP.NET中使用静态字段来缓存大型对象是不好的做法吗?

鉴于您对MemoryCache的理解是错误的,并且在MemoryCache中可靠地存储一些东西所需的代码比静态的要少,我不明白为什么您要坚持使用容易出错、有漏洞且更难使用的模式…

在任何情况下,有时使用静态缓存是合适的。但是,一般来说,您应该初始化静态值,并且在进程的生命周期内永远不要更改它们。一旦你开始摆弄东西,你就会开始感到疼痛。

这是一个老线程,但是当遇到一些未填充的数据缓存时,有一个简单的解决方案可以解决两个线程做相同工作的问题。

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.
            if (_dataYouWantCached != null)
                return _dataYouWantCached;
            _dataYouWantCached = SomeStaticDataAccess.LoadData();
            return _dataYouWantCached;
        }   
    }
}