在ASP.net中使用静态变量缓存信息是否可行?

24

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

该类会同时将更新的信息通过网络ping到其他web服务器(如果存在)。ping机制是一个Windows服务,缓存对象使用随机可用端口注册到该服务上。它还被用于其他一些功能。

数据量并不是很大。目前,我仅使用它来缓存用户密码哈希、权限、名称、电子邮件等信息。这样可以避免频繁地访问数据库。

我想知道这种方法是否有任何问题,以及是否有更好的缓存数据的方法?


你说的数据量有多大? - John Rutherford
我已经通过编辑问题来回答您的评论。 - Vincent McNabb
你能详细说明一下“pinging”解决方案吗?如果同一台服务器上有多个应用程序进程(w3wp),你会如何处理? - Doron Yaacoby
@Hitchhiker:我已经在问题中为您详细解释了。 - Vincent McNabb
+1,对于选择一个好答案,我看到很多人经常忘记缓存。 - Alex Lyman
5个回答

16
一个坑点:静态字段是应用程序域范围内的,并且增加负载会使服务器在池中生成更多应用程序域。如果您只从静态字段中读取数据,则不一定会出现问题,但是您将在内存中获取重复数据,并且每次创建或回收应用程序域时都会受到影响。
最好使用Cache对象-它就是为此类事情而设计的。
编辑:结果发现我在AppDomains方面错了(如评论所指出),在负载下将生成更多的Application实例,但它们都将在同一个AppDomain中运行。(但仍应该使用Cache对象!)

啊...谢谢让我感到愚蠢;-)我甚至没有意识到它的存在。不过,这并没有太大改变我的代码。谢谢。 - Vincent McNabb
你知道有没有描述“服务器在池中生成更多应用程序域”的文章? - sledgebox
我也想问这个问题,更多的应用程序域是什么意思?据我所知,每个应用程序进程只能获得一个域。如果您指定了Web Garden,则可能会有更多的进程。但是每个进程都有自己的缓存。 - AnthonyWJones

4
只要您能预期缓存永远不会增长到大于可用内存的大小,那么这很好。此外,请确保每个数据库只有一个应用程序实例,否则应用程序的不同实例中的缓存可能会“失去同步”。
在我工作的地方,我们有一个自制的O/RM,并且对于某些不太可能增长或更改的表格,我们做了与您类似的事情。因此,您所做的并不是前所未有的,事实上在我们的系统中,已经被证明是行之有效的。

4

你需要考虑的另一个问题是线程安全。所有应用程序请求都在同一AppDomain中运行,但可能在不同的线程上运行。访问静态变量必须考虑到它被多个线程访问的情况,这可能比你预想的要多一些开销。对于此目的,缓存对象更好。


0
嗯... "经典"的方法是应用程序缓存,但只要您从不更新静态变量,或者了解如果这样做会出现锁定问题,并且您知道它们可能随时在应用程序域重启时消失,那么我真的看不出使用静态变量有什么害处。

0

我建议您研究一下为应用程序提供分布式缓存的方法。您可以查看NCacheindeXus.Net

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


这需要花费金钱,目前只是一个业余项目。不打算从中获利。 - Vincent McNabb
1
这些产品与微软的Velocity相比怎么样? - WebDude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接