ASP.net中使用静态变量缓存信息可以吗?

Posted

技术标签:

【中文标题】ASP.net中使用静态变量缓存信息可以吗?【英文标题】:Is it OK to use static variables to cache information in ASP.net? 【发布时间】:2010-09-14 03:23:35 【问题描述】:

目前我正在 ASP.net 上使用 C# 3.5 开发项目管理应用程序。为了减少对数据库的访问,我使用静态变量缓存了大量信息。例如,用户列表保存在内存中的静态类中。该类在启动时从数据库中读取所有信息,并在发生更改时更新数据库,但它永远不需要从数据库中读取。

该类在写入数据库的同时使用更新的信息 ping 其他网络服务器(如果它们存在)。 ping 机制是一种 Windows 服务,缓存对象使用随机可用端口注册到该服务。它也用于其他用途。

数据量并没有那么大。目前我只是用它来缓存用户(密码哈希、权限、姓名、电子邮件等)。它只是保存了一堆对数据库的调用。

我想知道这种方法是否存在任何缺陷和/或是否有更好的方法来缓存数据?

【问题讨论】:

你在说多少数据? 我已通过编辑问题回答了您的评论。 您能否详细说明“ping”的解决方案?同一台服务器上存在多个应用进程(w3wp)的情况如何处理? @Hitchhiker:为你详细阐述了问题。 +1,为了选择一个好的答案,我看到人们经常忘记缓存。 【参考方案1】:

一个陷阱:静态字段的范围是每个应用程序域,增加的负载将使服务器在池中生成更多应用程序域。如果仅从静态数据中读取,这不一定是问题,但是您会在内存中获得重复数据,并且每次创建或回收应用程序域时都会受到打击。

最好使用 Cache 对象 - 它适用于这样的事情。

编辑:原来我对 AppDomains 的看法是错误的(正如 cmets 中指出的那样) - Application 的更多实例将在负载下生成,但它们都将在同一个 AppDomain 中运行。 (但你还是应该使用 Cache 对象!)

【讨论】:

啊...谢谢你让我觉得自己很愚蠢 ;-) 甚至没有意识到它的存在。尽管如此,并没有过多地改变我的代码。谢谢。 你知道任何描述“服务器在池中生成更多应用程序域”的文章吗? 我会第二个问题,这与创建更多应用程序域有关吗?据我所知,对于一个应用程序,每个进程只能获得一个域。如果您指定了一个网络花园,您可能需要预先处理更多流程。不过,每个都有自己的缓存。【参考方案2】:

只要您可以预期缓存永远不会增长到大于可用内存量的大小,就可以了。此外,请确保每个数据库只有一个此应用程序实例,否则应用程序不同实例中的缓存可能“不同步”。

在我工作的地方,我们有一个本土的 O/RM,我们做的事情与您对某些预计不会增长或变化太大的表所做的事情类似。所以,你所做的并不是史无前例的,事实上在我们的系统中,是经过验证的。

【讨论】:

【参考方案3】:

您必须考虑的另一个陷阱是线程安全。您的所有应用程序请求都在同一个 AppDomain 中运行,但可能来自不同的线程。访问静态变量必须考虑到它是从多个线程访问的。可能比您正在寻找的开销更多。缓存对象更适合此目的。

【讨论】:

【参考方案4】:

嗯...“经典”方法将是应用程序缓存,但前提是您从不更新静态变量,或者如果您这样做了了解锁定问题,并且您了解它们可以随时在 appdomain 重新启动时消失我真的没有看到使用静态的危害。

【讨论】:

【参考方案5】:

我建议您研究为您的应用设置分布式缓存的方法。你可以看看NCache或indeXus.Net

我建议这样做的原因是您采用了自己的临时方式来更新您正在缓存的信息。静态变量/引用很好,但它们不会更新/刷新(所以你必须自己处理老化),而且你似乎有一个分布式设置。

【讨论】:

要花钱,目前这只是一个爱好项目。不想从中赚钱。 与微软的 Velocity 相比,这些排名如何?

以上是关于ASP.net中使用静态变量缓存信息可以吗?的主要内容,如果未能解决你的问题,请参考以下文章

为 asp.net 网站缓存大对象

在 asp.net 中创建静态对象列表

ASP.NET - 受保护的变量

ASP.NET 网站中出现意外的第二个 AppDomain

为啥 FireFox 3.6.8 不缓存来自 asp.net 开发者服务器的静态内容?

静态 ID - ASP.NET Core 分布式缓存标记帮助程序