小议优化ASP.NET应用性能之Cache篇

王朝asp·作者佚名  2008-05-30
窄屏简体版  字體: |||超大  举报/纠错

虽然现在已经是宽带时代,小猫已经离我们渐渐远去,可作为WEB应用开发者来说,我们仍然有责任和义务不断地通过技术手段来优化WEB应用性能,让用户浏览时少一些等待,多一些爽快。

所幸的是,ASP.NET作为基于.Net Framework的WEB开发技术,它也享用着.Net Framework的优越性,.Net Framework为我们提供了良好的Cache技术,使我们能开发出速度更快、用户体验更好的WEB应用。命名空间System.Web.Caching提供了Cache类,其Cache的有效性依赖分以下三种情况:

1. 时间点(指定时间点内有效);

2. KEY值(KEY值作Cache项标识);

3. 文件或目录(指定文件或目录变更,则原Cache项不可用);

下面我就结合实际开发的应用跟大家分享一下使用Cache来提高ASP.NET应用的性能。

我们在开发中常常会遇到读取记录列表(例如最近更新的新闻列表Top N)、记录本身(例如一条新闻),用户访问的时候,这样的信息是否每次都要重复从数据库中读取呢?聪明的你可能知道,这完全是没必要的。

我们为了方便处理,不防设计一个SiteCache类(借鉴了CS中的CSCache.cs),并提供若干静态方法,来负责处理Cache项的添加和删除。

代码:

SiteCache.cs

1using System;

2using System.Collections;

3using System.Text.RegularExpressions;

4using System.Web;

5using System.Web.Caching;

6

7namespace Ycweb.Components

8{

9 public class SiteCache

10 {

11 private static readonly Cache _cache;

12 public static readonly int DayFactor;

13 private static int Factor;

14 public static readonly int HourFactor;

15 public static readonly int MinuteFactor;

16

17 static SiteCache()

18 {

19 DayFactor = 17280;

20 HourFactor = 720;

21 MinuteFactor = 12;

22 Factor = 5;

23 _cache = HttpRuntime.Cache;

24 }

25

26 private SiteCache()

27 {

28 }

29

30 public static void Clear()

31 {

32 IDictionaryEnumerator enumerator = _cache.GetEnumerator();

33 while (enumerator.MoveNext())

34 {

35 _cache.Remove(enumerator.Key.ToString());

36 }

37 }

38

39 public static object Get(string key)

40 {

41 return _cache[key];

42 }

43

44 public static void Insert(string key, object obj)

45 {

46 Insert(key, obj, null, 1);

47 }

48

49 public static void Insert(string key, object obj, int seconds)

50 {

51 Insert(key, obj, null, seconds);

52 }

53

54 public static void Insert(string key, object obj, CacheDependency dep)

55 {

56 Insert(key, obj, dep, HourFactor*12);

57 }

58

59 public static void Insert(string key, object obj, int seconds, CacheItemPriority priority)

60 {

61 Insert(key, obj, null, seconds, priority);

62 }

63

64 public static void Insert(string key, object obj, CacheDependency dep, int seconds)

65 {

66 Insert(key, obj, dep, seconds, CacheItemPriority.Normal);

67 }

68

69 public static void Insert(string key, object obj, CacheDependency dep, int seconds, CacheItemPriority priority)

70 {

71 if (obj != null)

72 {

73 _cache.Insert(key, obj, dep, DateTime.Now.AddSeconds((double) (Factor*seconds)), TimeSpan.Zero, priority, null);

74 }

75 }

76

77 public static void Max(string key, object obj)

78 {

79 Max(key, obj, null);

80 }

81

82 public static void Max(string key, object obj, CacheDependency dep)

83 {

84 if (obj != null)

85 {

86 _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.AboveNormal, null);

87 }

88 }

89

90 public static void MicroInsert(string key, object obj, int secondFactor)

91 {

92 if (obj != null)

93 {

94 _cache.Insert(key, obj, null, DateTime.Now.AddSeconds((double) (Factor*secondFactor)), TimeSpan.Zero);

95 }

96 }

97

98 public static void Remove(string key)

99 {

100 _cache.Remove(key);

101 }

102

103 public static void RemoveByPattern(string pattern)

104 {

105 IDictionaryEnumerator enumerator = _cache.GetEnumerator();

106 Regex regex1 = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);

107 while (enumerator.MoveNext())

108 {

109 if (regex1.IsMatch(enumerator.Key.ToString()))

110 {

111 _cache.Remove(enumerator.Key.ToString());

112 }

113 }

114 }

115

116 public static void ReSetFactor(int cacheFactor)

117 {

118 Factor = cacheFactor;

119 }

120

121

122

123 }

124}

其实该类主要就是利用前文所提及的关于Cache依赖项的第一点与第二点的特性来维护我们自己的Cache项。

有了SiteCache类,接下来看看如何使用它。还是以读取新闻TonN列表为例:

1public static RecordSet GetNewsSetTopN(string classCode,int topN,SortPostsBy orderBy, SortOrder sortOrder, string language)

2{

3 string cacheKey = string.Format("NewsSetTopN-LG:{0}:CC:{1}:TN:{2}:OB:{3}:SO:{4}", language,classCode,topN.ToString(), orderBy.ToString(),sortOrder.ToString());

4

5 //从上下文中读缓存项

6 RecordSet newsSet = HttpContext.Current.Items[cacheKey] as RecordSet;

7 if (newsSet == null)

8 {

9 //从HttpRuntime.Cache读缓存项

10 newsSet = SiteCache.Get(cacheKey) as RecordSet;

11 if (newsSet == null)

12 {

13 //直接从数据库从读取

14 CommonDataProvider dp=CommonDataProvider.Instance();

15 newsSet =dp.GetNewsSetTopN(language,classCode,topN,orderBy,sortOrder);

16 //并将结果缓存到HttpRuntime.Cache中

17 SiteCache.Insert(cacheKey, newsSet, 60, CacheItemPriority.Normal);

18 }

19

20 }

21return newsSet;

22}

这样在5分钟内就不用重复访问数据库了来读该列表了,当然,也有人会问,如果在这5分钟内某条新闻删除了或修改了怎么办,没关系,我们在删除或修改时可以根据Cache KEY来强制删除该Cache项,当然,如果你觉得你对列表的时效性不是特别在意,你可以不强制删除该Cache项,让Cache项定义的时间点自动失效。当然,最好还是提供一个方法按匹配模式项来强行删除Cache项就可以了,例如:

1/**//// <summary>

2/// 删除匹配的NewsSetTopN列表的Cache项

3/// </summary>

4public static void ClearNewsSetTopNCache(string language,string classCode,int topN)

5{

6 string cacheKey = string.Format("NewsSetTopN-LG:{0}:CC:{1}:TN:{2}",language,classCode,topN.ToString());

7 SiteCache.RemoveByPattern(cacheKey);

8}

9

发布新闻后调用静态方法ClearNewsSetTopNCache()强行清除原来的TopN缓存项,例如:

1/**//// <summary>

2/// 发布(新建)新闻

3/// </summary>

4/// <param name="post">新闻实例</param>

5/// <returns>返回状态</returns>

6public static int Create(News post)

7{

8 int status;

9 CommonDataProvider dp=CommonDataProvider.Instance();

10 dp.CreateUpdateDeleteNews(post, DataAction.Create, out status);

11 //强制清除匹配的缓存项

12 ClearNewsSetTopNCache (post.Language, post.ClassCode,Globals.GetSiteSetting.NewsListTopN);

13 return status;

14}

That's all.若有不妥之处还望各位同行指正。

http://www.cnblogs.com/aspsir/archive/2006/07/27/461229.html

举报/纠错
 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005-2025 王朝網路 版權所有 聯絡我們導航