讨论一下类似BlogEngine为何要一次性加载所有Post到内存
试验了一下给BlogEngine生成10000个post 程序第一次运行时等待的时间让我想自杀(白屏了近2分钟)
看了一下代码,发现BlogEngine在第一次运行时候加载所有Post(从数据库)到List内,类似(Early initialization)
当新添加post时,给数据库(xml/database)内加入该post同时给List内追加该post
删除一个post时候从数据库(xml/database)内删除并从List内remove该post
1
2
private string _Content;
3
/// <summary>
4
/// Gets or sets the Content or the post.
5
/// </summary>
6
public string Content
7
{
8
get
9
{
10
if ( _Content == null )
11
{
12
_Content = LoadPostContent( this.Id );
13
}
14
return _Content;
15
}
16
set
17
{
18
if ( _Content != value )
19
MarkDirty( "Content" );
20
_Content = value;
21
}
22
}
23
private string LoadPostContent(Guid id)
24
{
25
string content = null;
26
27
string key = string.Format("Be:Content:{0}",id);
28
29
// if there is no content cached
30
object obj = HttpContext.Current.Cache.Get(key);
31
if(obj == null)
32
{
33
// load the post's content from provider here
34
content = BlogService.LoadPostContent( id );
35
36
HttpContext.Current.Cache.Insert(key, content, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero);
37
38
// if use xml store the data
39
// 更丑陋点的 new CacheDependency(_Folder + "posts\\" + id.ToString() + ".xml") in the Cache.Insert Method
40
}
41
42
}
43
44
private static object _SyncRoot = new object();
45
private static List<Post> _Posts;
46
/// <summary>
47
/// A sorted collection of all posts in the blog.
48
/// Sorted by date.
49
/// </summary>
50
public static List<Post> Posts
51
{
52
get
53
{
54
lock (_SyncRoot)
55
{
56
if (_Posts == null)
57
{
58
//in provider the 'FillPosts' method' dose not return the 'real' content' per post;
59
60
_Posts = BlogService.FillPosts( );
61
}
62
return _Posts;
63
}
64
}
65
}
66
67
in XmlBlogProvider
68
69
/// <summary>
70
/// Retrieves a post based on the specified Id.
71
/// </summary>
72
public override Post SelectPost(Guid id)
73
{
74
string fileName = _Folder + "posts\\" + id.ToString() + ".xml";
75
Post post = new Post();
76
XmlDocument doc = new XmlDocument();
77
doc.Load(fileName);
78
79
post.Title = doc.SelectSingleNode("post/title").InnerText;
80
post.Description = doc.SelectSingleNode("post/description").InnerText;
81
82
post.Content = null; // dose not return the 'real' content'
83
84
post.DateCreated = DateTime.Parse(doc.SelectSingleNode("post/pubDate").InnerText);
85
post.DateModified = DateTime.Parse(doc.SelectSingleNode("post/lastModified").InnerText);
86
87
// setting other filed
88
89
return post;
90
}
91
Post class in Business object layer
92
93
private string _Content;
94
/// <summary>
95
/// Gets or sets the Content or the post.
96
/// </summary>
97
public string Content
98
{
99
get
100
{
101
if ( _Content == null )
102
{
103
_Content = LoadPostContent( this.Id );
104
}
105
return _Content;
106
}
107
set
108
{
109
if ( _Content != value )
110
MarkDirty( "Content" );
111
_Content = value;
112
}
113
}
114
private string LoadPostContent(Guid id)
115
{
116
string key = string.Format("Be:Content:{0}",id);
117
string content = null;
118
// if there is no content cached by id
119
object obj = HttpContext.Current.Cache.Get(key);
120
if(obj == null)
121
{
122
// load the post's content from provider here
123
content = BlogService.LoadPostContent( id );
124
125
HttpContext.Current.Cache.Insert(key, content, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero);
126
127
// if use xml store the data
128
// we can use a CacheDependency like new CacheDependency(_Folder + "posts\\" + id.ToString() + ".xml") in the Cache.Insert Method
129
130
return content;
131
}
132
return (strong)obj;
133
134
}
135
136
private static object _SyncRoot = new object();
137
private static List<Post> _Posts;
138
/// <summary>
139
/// A sorted collection of all posts in the blog.
140
/// Sorted by date.
141
/// </summary>
142
public static List<Post> Posts
143
{
144
get
145
{
146
lock (_SyncRoot)
147
{
148
if (_Posts == null)
149
{
150
//in provider the 'FillPosts' method' dose not return the 'real' content' per post;
151
152
_Posts = BlogService.FillPosts( );
153
}
154
return _Posts;
155
}
156
}
157
}
158
159
in XmlBlogProvider
160
161
/// <summary>
162
/// Retrieves a post based on the specified Id.
163
/// </summary>
164
public override Post SelectPost(Guid id)
165
{
166
string fileName = _Folder + "posts\\" + id.ToString() + ".xml";
167
Post post = new Post();
168
XmlDocument doc = new XmlDocument();
169
doc.Load(fileName);
170
171
post.Title = doc.SelectSingleNode("post/title").InnerText;
172
post.Description = doc.SelectSingleNode("post/description").InnerText;
173
174
post.Content = null; // dose not return the 'real' content'
175
176
post.DateCreated = DateTime.Parse(doc.SelectSingleNode("post/pubDate").InnerText);
177
post.DateModified = DateTime.Parse(doc.SelectSingleNode("post/lastModified").InnerText);
178
179
// setting other fileds
180
181
return post;
182
}

2
private string _Content;3
/// <summary>4
/// Gets or sets the Content or the post.5
/// </summary>6
public string Content7
{8
get9
{10
if ( _Content == null )11
{12
_Content = LoadPostContent( this.Id );13
}14
return _Content;15
}16
set17
{18
if ( _Content != value )19
MarkDirty( "Content" );20
_Content = value;21
}22
}23
private string LoadPostContent(Guid id)24
{ 25
string content = null;26
27
string key = string.Format("Be:Content:{0}",id);28
29
// if there is no content cached30
object obj = HttpContext.Current.Cache.Get(key);31
if(obj == null)32
{33
// load the post's content from provider here34
content = BlogService.LoadPostContent( id );35
36
HttpContext.Current.Cache.Insert(key, content, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero);37
38
// if use xml store the data 39
// 更丑陋点的 new CacheDependency(_Folder + "posts\\" + id.ToString() + ".xml") in the Cache.Insert Method 40
}41

42
}43

44
private static object _SyncRoot = new object();45
private static List<Post> _Posts;46
/// <summary>47
/// A sorted collection of all posts in the blog.48
/// Sorted by date.49
/// </summary>50
public static List<Post> Posts51
{52
get53
{54
lock (_SyncRoot)55
{56
if (_Posts == null)57
{58
//in provider the 'FillPosts' method' dose not return the 'real' content' per post; 59

60
_Posts = BlogService.FillPosts( );61
}62
return _Posts;63
}64
}65
}66

67
in XmlBlogProvider68

69
/// <summary>70
/// Retrieves a post based on the specified Id.71
/// </summary>72
public override Post SelectPost(Guid id)73
{74
string fileName = _Folder + "posts\\" + id.ToString() + ".xml";75
Post post = new Post();76
XmlDocument doc = new XmlDocument();77
doc.Load(fileName);78

79
post.Title = doc.SelectSingleNode("post/title").InnerText;80
post.Description = doc.SelectSingleNode("post/description").InnerText;81

82
post.Content = null; // dose not return the 'real' content'83

84
post.DateCreated = DateTime.Parse(doc.SelectSingleNode("post/pubDate").InnerText);85
post.DateModified = DateTime.Parse(doc.SelectSingleNode("post/lastModified").InnerText);86
87
// setting other filed88

89
return post;90
}91
Post class in Business object layer92

93
private string _Content;94
/// <summary>95
/// Gets or sets the Content or the post.96
/// </summary>97
public string Content98
{99
get100
{101
if ( _Content == null )102
{103
_Content = LoadPostContent( this.Id );104
}105
return _Content;106
}107
set108
{109
if ( _Content != value )110
MarkDirty( "Content" );111
_Content = value;112
}113
}114
private string LoadPostContent(Guid id)115
{ 116
string key = string.Format("Be:Content:{0}",id);117
string content = null;118
// if there is no content cached by id119
object obj = HttpContext.Current.Cache.Get(key);120
if(obj == null)121
{122
// load the post's content from provider here123
content = BlogService.LoadPostContent( id );124
125
HttpContext.Current.Cache.Insert(key, content, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero);126
127
// if use xml store the data 128
// we can use a CacheDependency like new CacheDependency(_Folder + "posts\\" + id.ToString() + ".xml") in the Cache.Insert Method 129
130
return content;131
}132
return (strong)obj;133

134
}135

136
private static object _SyncRoot = new object();137
private static List<Post> _Posts;138
/// <summary>139
/// A sorted collection of all posts in the blog.140
/// Sorted by date.141
/// </summary>142
public static List<Post> Posts143
{144
get145
{146
lock (_SyncRoot)147
{148
if (_Posts == null)149
{150
//in provider the 'FillPosts' method' dose not return the 'real' content' per post; 151

152
_Posts = BlogService.FillPosts( );153
}154
return _Posts;155
}156
}157
}158

159
in XmlBlogProvider160

161
/// <summary>162
/// Retrieves a post based on the specified Id.163
/// </summary>164
public override Post SelectPost(Guid id)165
{166
string fileName = _Folder + "posts\\" + id.ToString() + ".xml";167
Post post = new Post();168
XmlDocument doc = new XmlDocument();169
doc.Load(fileName);170

171
post.Title = doc.SelectSingleNode("post/title").InnerText;172
post.Description = doc.SelectSingleNode("post/description").InnerText;173

174
post.Content = null; // dose not return the 'real' content'175

176
post.DateCreated = DateTime.Parse(doc.SelectSingleNode("post/pubDate").InnerText);177
post.DateModified = DateTime.Parse(doc.SelectSingleNode("post/lastModified").InnerText);178
179
// setting other fileds180

181
return post;182
}个人觉得 是否应该对于Content、Comment这种占用大量内存的字段是否该采用类似Lazy Initialization 的方式
说明:第一次加载所有post时候 post list内的item不带真实的comtent和comment等
然后在用到的时候再从数据库读取,然后放入缓存,下次备用
这样Posts内的item都变的瘦多了,类似于延迟初始化(Lazy Initialization )
请大家讨论讨论,谢谢!


浙公网安备 33010602011771号