讨论一下类似BlogEngine为何要一次性加载所有Post到内存
试验了一下给BlogEngine生成10000个post 程序第一次运行时等待的时间让我想自杀(白屏了近2分钟)
看了一下代码,发现BlogEngine在第一次运行时候加载所有Post(从数据库)到List内,类似(Early initialization)
当新添加post时,给数据库(xml/database)内加入该post同时给List内追加该post
删除一个post时候从数据库(xml/database)内删除并从List内remove该post
1
2private string _Content;
3/// <summary>
4/// Gets or sets the Content or the post.
5/// </summary>
6public 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}
23private 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
44private static object _SyncRoot = new object();
45private static List<Post> _Posts;
46/// <summary>
47/// A sorted collection of all posts in the blog.
48/// Sorted by date.
49/// </summary>
50public 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
67in XmlBlogProvider
68
69/// <summary>
70/// Retrieves a post based on the specified Id.
71/// </summary>
72public 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}
91Post class in Business object layer
92
93private string _Content;
94/// <summary>
95/// Gets or sets the Content or the post.
96/// </summary>
97public 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}
114private 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
136private static object _SyncRoot = new object();
137private static List<Post> _Posts;
138/// <summary>
139/// A sorted collection of all posts in the blog.
140/// Sorted by date.
141/// </summary>
142public 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
159in XmlBlogProvider
160
161/// <summary>
162/// Retrieves a post based on the specified Id.
163/// </summary>
164public 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}
2private string _Content;
3/// <summary>
4/// Gets or sets the Content or the post.
5/// </summary>
6public 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}
23private 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
44private static object _SyncRoot = new object();
45private static List<Post> _Posts;
46/// <summary>
47/// A sorted collection of all posts in the blog.
48/// Sorted by date.
49/// </summary>
50public 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
67in XmlBlogProvider
68
69/// <summary>
70/// Retrieves a post based on the specified Id.
71/// </summary>
72public 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}
91Post class in Business object layer
92
93private string _Content;
94/// <summary>
95/// Gets or sets the Content or the post.
96/// </summary>
97public 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}
114private 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
136private static object _SyncRoot = new object();
137private static List<Post> _Posts;
138/// <summary>
139/// A sorted collection of all posts in the blog.
140/// Sorted by date.
141/// </summary>
142public 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
159in XmlBlogProvider
160
161/// <summary>
162/// Retrieves a post based on the specified Id.
163/// </summary>
164public 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}
个人觉得 是否应该对于Content、Comment这种占用大量内存的字段是否该采用类似Lazy Initialization 的方式
说明:第一次加载所有post时候 post list内的item不带真实的comtent和comment等
然后在用到的时候再从数据库读取,然后放入缓存,下次备用
这样Posts内的item都变的瘦多了,类似于延迟初始化(Lazy Initialization )
请大家讨论讨论,谢谢!