28 Jul 2007

中国EDONG网(中国排名第16的IDC)的技术力量和他的24小时客服。

这篇post写好后发现在博客园不能保存,原因是内容包含违禁内容。

只有写到其他地方,再挂个链接了。

http://spaces.huash.com/index.php/uid-133969-action-viewspace-itemid-240537

另外说一下,用了用感觉Discuz/ X-Space 真是个不错的博客、圈子软件,希望雪人和他同事们的DisuczNT做的更好。



----------------------------------------------------------------------------------------------------------
注:

此post不接受任何其他IDC评论,不接受其对其他IDC的推荐。
任何
评论中出现任何IDC网站相关链接都将被删除。
本人有权认定您的评论是否是枪手文章或广告内容。

评论前请看右边的公告,谢谢合作!

----------------------------------------------------------------------------------------------------------

23 Jul 2007

在自定义控件中实现ICallbackEventHandler接口不经过回发而实现客户端回掉

 

在自定义控件中实现ICallbackEventHandler接口不经过回发而实现客户端回掉 
Asp.Net2.0中新增了ICallbackEventHandler接口,用于指示控件可以作器的回事件的目
MSDN中的描述:

实现 ICallbackEventHandler 接口的控件的示例包括 GridViewDetailsView TreeView 控件。当回事件以实现 ICallbackEventHandler 接口的控件标时,将把事件量作参数传递 RaiseCallbackEvent 方法以事件,并且GetCallbackResult 方法返回回

ICallbackEventHandler成员有:

 

 

名称

 


 

 

 

GetCallbackResult

 

返回以控件的回事件的果。

 

 

 

RaiseCallbackEvent

 

理以控件的回事件。

 

 
如下代码实现一个不经过回发而实现客户端回掉的CheckBox



//------------------------------------------------------------------------------<br />// <copyright company="Meibo Wu www.github.com"><br />// Copyright (c) www.github.com All rights reserved.<br />// </copyright><br />//------------------------------------------------------------------------------<br />using System;<br />using System.Drawing;<br />using System.Collections;<br />using System.ComponentModel;<br />using System.Web;<br />using System.Web.UI;<br />using System.Web.UI.WebControls;<br />namespace HBZ<br />{<br />/// <summary><br />/// A Asynchronous AutoPostback Checkbox Control<br />/// </summary><br />[DefaultEvent("CheckedChanged")]<br />[ControlValueProperty("Checked")]<br />[DefaultProperty("Text")]<br />public class AsynchronousCheckBox : WebControl, INamingContainer, ICallbackEventHandler<br />{<br />#region Delegates<br />/// <summary><br />/// The delegate for the checked changed event<br />/// </summary><br />///<br /><span name="sender" class="mceItemParam"></span></param><br />///<br /><span name="e" class="mceItemParam"></span></param><br />public delegate void CheckedChangedEventHander(object sender, CheckChangedEventArgs e);<br />#endregion<br />#region Events<br />private static readonly object eventCheckedChanged;<br />/// <summary><br />/// The checked changed event.<br />/// </summary><br />public event CheckedChangedEventHander CheckedChanged<br />{<br />add<br />{<br />Events.AddHandler(eventCheckedChanged, value);<br />}<br />remove<br />{<br />Events.RemoveHandler(eventCheckedChanged, value);<br />}<br />}<br />#endregion<br />#region Constructors<br />/// <summary><br />/// Static Constructor<br />/// </summary><br />static AsynchronousCheckBox()<br />{<br />eventCheckedChanged = new object();<br />}<br />/// <summary><br />/// Constructor<br />/// </summary><br />public AsynchronousCheckBox()<br />: base(HtmlTextWriterTag.Input)<br />{<br />}<br />#endregion<br />#region Properties<br />/// <summary><br />/// Gets or sets a value indicating whether the Lable Text<br />/// </summary><br />[Description("Gets or sets a value indicating whether the Lable Text")]<br />public virtual string Text<br />{<br />get<br />{<br />return (string)ViewState["Text"];<br />}<br />set<br />{<br />this.ViewState["Text"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the 'Client CallBack Script Name'<br />/// </summary><br />[Description("Gets or sets a value indicating whether the 'Client CallBack Script function Name'")]<br />public string ClientCallBackScript<br />{<br />get<br />{<br />object o = ViewState["ClientCallBackScript"];<br />return o == null ? "null" : o.ToString();<br />}<br />set<br />{<br />ViewState["ClientCallBackScript"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the checkbox 's checked<br />/// </summary><br />[Description("Gets or sets a value indicating whether the checkbox 's checked")]<br />public bool Checked<br />{<br />get<br />{<br />object o = ViewState["Checked"];<br />return o == null ? false : (bool)o;<br />}<br />set<br />{<br />ViewState["Checked"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the Text 's cssClass<br />/// </summary><br />[Description("Gets or sets a value indicating whether the Text 's cssClass")]<br />public string TextCss<br />{<br />get<br />{<br />return (string)ViewState["TextCss"];<br />}<br />set<br />{<br />ViewState["TextCss"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the Label 's position<br />/// </summary><br />public virtual TextAlign TextAlign<br />{<br />get<br />{<br />object o = ViewState["TextAlign"];<br />if (o != null)<br />{<br />return (TextAlign)o;<br />}<br />return TextAlign.Right;<br />}<br />set<br />{<br />if ((value <textalign.left) || (value > TextAlign.Right))<br />{<br />throw new ArgumentOutOfRangeException("value");<br />}<br />ViewState["TextAlign"] = value;<br />}<br />}<br />#endregion<br />#region Render Meghods<br />/// <summary><br />///<br />/// </summary><br />///<br /><span name="writer" class="mceItemParam"></span></param><br />protected override void Render(HtmlTextWriter writer)<br />{<br />if (TextAlign == TextAlign.Left)<br />{<br />RenderLabel(writer);<br />base.Render(writer);<br />}<br />else<br />{<br />base.Render(writer);<br />RenderLabel(writer);<br />}<br />}<br />/// <summary><br />/// Render Label<br />/// </summary><br />///<br /><span name="writer" class="mceItemParam"></span></param><br />private void RenderLabel(HtmlTextWriter writer)<br />{<br />if (string.IsNullOrEmpty(Text))<br />{<br />return;<br />}<br />writer.Write("<label");<br />writer.WriteAttribute("for", ClientID);<br />if (!string.IsNullOrEmpty(TextCss))<br />{<br />writer.WriteAttribute("class", TextCss);<br />}<br />writer.Write(">");<br />writer.Write(Text);<br />writer.WriteEndTag("label");<br />}<br />/// <summary><br />/// Override the AddAttributesToRender method<br />/// </summary><br />///<br /><span name="writer" class="mceItemParam"></span></param><br />protected override void AddAttributesToRender(HtmlTextWriter writer)<br />{<br />if (base.Page == null)<br />{<br />base.Page.VerifyRenderingInServerForm(this);<br />}<br />string callbackReference<br />= Page.ClientScript.GetCallbackEventReference(this, "this.checked", ClientCallBackScript, null);<br />writer.AddAttribute(HtmlTextWriterAttribute.Onclick, callbackReference);<br />writer.AddAttribute(HtmlTextWriterAttribute.Type, "checkbox");<br />if (Checked)<br />{<br />writer.AddAttribute(HtmlTextWriterAttribute.Checked, "checked");<br />}<br />if (!Enabled)<br />{<br />writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");<br />}<br />if (!string.IsNullOrEmpty(ToolTip))<br />{<br />writer.AddAttribute(HtmlTextWriterAttribute.Title, ToolTip);<br />}<br />base.AddAttributesToRender(writer);<br />}<br />#endregion<br />#region On Checked Changed<br />/// <summary><br />/// Invoke the check changed event.<br />/// </summary><br />///<br /><span name="sender" class="mceItemParam"></span></param><br />///<br /><span name="e" class="mceItemParam"></span></param><br />protected virtual void OnCheckedChanged(object sender, CheckChangedEventArgs e)<br />{<br />CheckedChangedEventHander hander = Events[eventCheckedChanged] as CheckedChangedEventHander;<br />if (hander != null)<br />{<br />Checked = e.Checked;<br />hander(this, e);<br />}<br />}<br />#endregion<br />#region ICallbackEventHandler Members<br />/// <summary><br />/// Get the result of a client side callback.<br />/// </summary><br />/// <returns>The callback result string.</returns><br />public string GetCallbackResult()<br />{<br />return Checked.ToString();<br />}<br />/// <summary><br />/// Raise the client callback event<br />/// </summary><br />///<br /><span name="eventArgument" class="mceItemParam"></span>The event arguments.</param><br />public void RaiseCallbackEvent(string eventArgument)<br />{<br />bool isChecked = Boolean.Parse(eventArgument);<br />CheckChangedEventArgs args = new CheckChangedEventArgs(isChecked);<br />OnCheckedChanged(this, args);<br />}<br />#endregion<br />}<br />}<br />//------------------------------------------------------------------------------<br />// <copyright company="Meibo Wu www.github.com"><br />// Copyright (c) www.github.com All rights reserved.<br />// </copyright><br />//------------------------------------------------------------------------------<br />using System;<br />using System.Drawing;<br />using System.Collections;<br />using System.ComponentModel;<br />using System.Web;<br />using System.Web.UI;<br />using System.Web.UI.WebControls;<br />namespace HBZ<br />{<br />/// <summary><br />///<br />/// </summary><br />public class CheckChangedEventArgs:EventArgs<br />{<br />/// <summary><br />///<br />/// </summary><br />///<br /><span name="_isChecked" class="mceItemParam"></span></param><br />public CheckChangedEventArgs(bool _isChecked)<br />{<br />isChecked = _isChecked;<br />}<br />private bool isChecked = false;<br />/// <summary><br />///<br />/// </summary><br />public bool Checked<br />{<br />get<br />{<br />return isChecked;<br />}<br />}<br />}<br />}<br />
         http://www.github.com/private/5504/default.aspx

23 Jul 2007

在自定义控件中实现ICallbackEventHandler接口不经过回发而实现客户端回掉

 

在自定义控件中实现ICallbackEventHandler接口不经过回发而实现客户端回掉 
Asp.Net2.0中新增了ICallbackEventHandler接口,用于指示控件可以作器的回事件的目
MSDN中的描述:

实现 ICallbackEventHandler 接口的控件的示例包括 GridViewDetailsView TreeView 控件。当回事件以实现 ICallbackEventHandler 接口的控件标时,将把事件量作参数传递 RaiseCallbackEvent 方法以事件,并且GetCallbackResult 方法返回回

ICallbackEventHandler成员有:

 

 

名称

 


 

 

 

GetCallbackResult

 

返回以控件的回事件的果。

 

 

 

RaiseCallbackEvent

 

理以控件的回事件。

 

 
如下代码实现一个不经过回发而实现客户端回掉的CheckBox



//------------------------------------------------------------------------------<br />// <copyright company="Meibo Wu www.github.com"><br />// Copyright (c) www.github.com All rights reserved.<br />// </copyright><br />//------------------------------------------------------------------------------<br />using System;<br />using System.Drawing;<br />using System.Collections;<br />using System.ComponentModel;<br />using System.Web;<br />using System.Web.UI;<br />using System.Web.UI.WebControls;<br />namespace HBZ<br />{<br />/// <summary><br />/// A Asynchronous AutoPostback Checkbox Control<br />/// </summary><br />[DefaultEvent("CheckedChanged")]<br />[ControlValueProperty("Checked")]<br />[DefaultProperty("Text")]<br />public class AsynchronousCheckBox : WebControl, INamingContainer, ICallbackEventHandler<br />{<br />#region Delegates<br />/// <summary><br />/// The delegate for the checked changed event<br />/// </summary><br />///<br /><span name="sender" class="mceItemParam"></span></param><br />///<br /><span name="e" class="mceItemParam"></span></param><br />public delegate void CheckedChangedEventHander(object sender, CheckChangedEventArgs e);<br />#endregion<br />#region Events<br />private static readonly object eventCheckedChanged;<br />/// <summary><br />/// The checked changed event.<br />/// </summary><br />public event CheckedChangedEventHander CheckedChanged<br />{<br />add<br />{<br />Events.AddHandler(eventCheckedChanged, value);<br />}<br />remove<br />{<br />Events.RemoveHandler(eventCheckedChanged, value);<br />}<br />}<br />#endregion<br />#region Constructors<br />/// <summary><br />/// Static Constructor<br />/// </summary><br />static AsynchronousCheckBox()<br />{<br />eventCheckedChanged = new object();<br />}<br />/// <summary><br />/// Constructor<br />/// </summary><br />public AsynchronousCheckBox()<br />: base(HtmlTextWriterTag.Input)<br />{<br />}<br />#endregion<br />#region Properties<br />/// <summary><br />/// Gets or sets a value indicating whether the Lable Text<br />/// </summary><br />[Description("Gets or sets a value indicating whether the Lable Text")]<br />public virtual string Text<br />{<br />get<br />{<br />return (string)ViewState["Text"];<br />}<br />set<br />{<br />this.ViewState["Text"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the 'Client CallBack Script Name'<br />/// </summary><br />[Description("Gets or sets a value indicating whether the 'Client CallBack Script function Name'")]<br />public string ClientCallBackScript<br />{<br />get<br />{<br />object o = ViewState["ClientCallBackScript"];<br />return o == null ? "null" : o.ToString();<br />}<br />set<br />{<br />ViewState["ClientCallBackScript"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the checkbox 's checked<br />/// </summary><br />[Description("Gets or sets a value indicating whether the checkbox 's checked")]<br />public bool Checked<br />{<br />get<br />{<br />object o = ViewState["Checked"];<br />return o == null ? false : (bool)o;<br />}<br />set<br />{<br />ViewState["Checked"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the Text 's cssClass<br />/// </summary><br />[Description("Gets or sets a value indicating whether the Text 's cssClass")]<br />public string TextCss<br />{<br />get<br />{<br />return (string)ViewState["TextCss"];<br />}<br />set<br />{<br />ViewState["TextCss"] = value;<br />}<br />}<br />/// <summary><br />/// Gets or sets a value indicating whether the Label 's position<br />/// </summary><br />public virtual TextAlign TextAlign<br />{<br />get<br />{<br />object o = ViewState["TextAlign"];<br />if (o != null)<br />{<br />return (TextAlign)o;<br />}<br />return TextAlign.Right;<br />}<br />set<br />{<br />if ((value <textalign.left) || (value > TextAlign.Right))<br />{<br />throw new ArgumentOutOfRangeException("value");<br />}<br />ViewState["TextAlign"] = value;<br />}<br />}<br />#endregion<br />#region Render Meghods<br />/// <summary><br />///<br />/// </summary><br />///<br /><span name="writer" class="mceItemParam"></span></param><br />protected override void Render(HtmlTextWriter writer)<br />{<br />if (TextAlign == TextAlign.Left)<br />{<br />RenderLabel(writer);<br />base.Render(writer);<br />}<br />else<br />{<br />base.Render(writer);<br />RenderLabel(writer);<br />}<br />}<br />/// <summary><br />/// Render Label<br />/// </summary><br />///<br /><span name="writer" class="mceItemParam"></span></param><br />private void RenderLabel(HtmlTextWriter writer)<br />{<br />if (string.IsNullOrEmpty(Text))<br />{<br />return;<br />}<br />writer.Write("<label");<br />writer.WriteAttribute("for", ClientID);<br />if (!string.IsNullOrEmpty(TextCss))<br />{<br />writer.WriteAttribute("class", TextCss);<br />}<br />writer.Write(">");<br />writer.Write(Text);<br />writer.WriteEndTag("label");<br />}<br />/// <summary><br />/// Override the AddAttributesToRender method<br />/// </summary><br />///<br /><span name="writer" class="mceItemParam"></span></param><br />protected override void AddAttributesToRender(HtmlTextWriter writer)<br />{<br />if (base.Page == null)<br />{<br />base.Page.VerifyRenderingInServerForm(this);<br />}<br />string callbackReference<br />= Page.ClientScript.GetCallbackEventReference(this, "this.checked", ClientCallBackScript, null);<br />writer.AddAttribute(HtmlTextWriterAttribute.Onclick, callbackReference);<br />writer.AddAttribute(HtmlTextWriterAttribute.Type, "checkbox");<br />if (Checked)<br />{<br />writer.AddAttribute(HtmlTextWriterAttribute.Checked, "checked");<br />}<br />if (!Enabled)<br />{<br />writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");<br />}<br />if (!string.IsNullOrEmpty(ToolTip))<br />{<br />writer.AddAttribute(HtmlTextWriterAttribute.Title, ToolTip);<br />}<br />base.AddAttributesToRender(writer);<br />}<br />#endregion<br />#region On Checked Changed<br />/// <summary><br />/// Invoke the check changed event.<br />/// </summary><br />///<br /><span name="sender" class="mceItemParam"></span></param><br />///<br /><span name="e" class="mceItemParam"></span></param><br />protected virtual void OnCheckedChanged(object sender, CheckChangedEventArgs e)<br />{<br />CheckedChangedEventHander hander = Events[eventCheckedChanged] as CheckedChangedEventHander;<br />if (hander != null)<br />{<br />Checked = e.Checked;<br />hander(this, e);<br />}<br />}<br />#endregion<br />#region ICallbackEventHandler Members<br />/// <summary><br />/// Get the result of a client side callback.<br />/// </summary><br />/// <returns>The callback result string.</returns><br />public string GetCallbackResult()<br />{<br />return Checked.ToString();<br />}<br />/// <summary><br />/// Raise the client callback event<br />/// </summary><br />///<br /><span name="eventArgument" class="mceItemParam"></span>The event arguments.</param><br />public void RaiseCallbackEvent(string eventArgument)<br />{<br />bool isChecked = Boolean.Parse(eventArgument);<br />CheckChangedEventArgs args = new CheckChangedEventArgs(isChecked);<br />OnCheckedChanged(this, args);<br />}<br />#endregion<br />}<br />}<br />//------------------------------------------------------------------------------<br />// <copyright company="Meibo Wu www.github.com"><br />// Copyright (c) www.github.com All rights reserved.<br />// </copyright><br />//------------------------------------------------------------------------------<br />using System;<br />using System.Drawing;<br />using System.Collections;<br />using System.ComponentModel;<br />using System.Web;<br />using System.Web.UI;<br />using System.Web.UI.WebControls;<br />namespace HBZ<br />{<br />/// <summary><br />///<br />/// </summary><br />public class CheckChangedEventArgs:EventArgs<br />{<br />/// <summary><br />///<br />/// </summary><br />///<br /><span name="_isChecked" class="mceItemParam"></span></param><br />public CheckChangedEventArgs(bool _isChecked)<br />{<br />isChecked = _isChecked;<br />}<br />private bool isChecked = false;<br />/// <summary><br />///<br />/// </summary><br />public bool Checked<br />{<br />get<br />{<br />return isChecked;<br />}<br />}<br />}<br />}<br />
         http://www.github.com/private/5504/default.aspx

07 Jul 2007

.Net专业人力资源网上线试运行.

自己也是搞.net开发的,经常看到有些朋友在csdn发求职/招聘贴
国内而现有的大招聘网站又未见专门为我们这拨人有个专门分类。就花了点时间做了这样一个网站。
今天开始试运行。

希望为.Net开发人员和企业提供一个良好的求职招聘平台!

.Net专业人力资源网




欢迎大家提出意见和建议
http://www.dotnetjobs.cn/FeedBack.aspx

07 Jul 2007

.Net专业人力资源网上线试运行.

自己也是搞.net开发的,经常看到有些朋友在csdn发求职/招聘贴
国内而现有的大招聘网站又未见专门为我们这拨人有个专门分类。就花了点时间做了这样一个网站。
今天开始试运行。

希望为.Net开发人员和企业提供一个良好的求职招聘平台!

.Net专业人力资源网




欢迎大家提出意见和建议
http://www.dotnetjobs.cn/FeedBack.aspx

04 Jul 2007

讨论一下类似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}

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

04 Jul 2007

讨论一下类似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}

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

21 Jun 2007

GotDotNet.Com要退休了


http://www.gotdotnet.com/




GotDotNet Phase-out Announcement
Microsoft announces changes to the GotDotNet phase-out schedule.
Overall phase-out will be completed in summer 2007.



  
Based on your feedback, we’ve made some adjustments to our schedule:

  • CodeGallery phase-out – Rescheduled to July 2007 (original phase-out date was April 24, 2007)
    This gives CodeGallery owners more time to migrate. We suggest CodePlex as an excellent alternative. Please contact CodePlex support with any questions you may have.
  • User Samples phase-out – Schedule update in Fall ‘07
    We will not phase-out User Samples until we can provide customers with greater alternative. We will update you with further schedule information in Fall, 2007.
  • Workspaces phase-out – Completed on June 19, 2007.
    We suggest CodePlex as an excellent alternative. Please contact the CodePlex support staff with any questions you may have.


  •    We appreciate the input you’ve given us regarding the GotDotNet phase-out. We will keep you posted as we move forward.

    We are phasing out GotDotNet for the following reasons:

  • Microsoft wants to reinvest the resources currently used for GotDotNet in new and better community features for our customers

  • Traffic and usage of GotDotNet features has significantly decreased over the last six months
  • Microsoft wants to eliminate redundant functionality between GotDotNet and other community resources provided by Microsoft

  • Other Microsoft sites
    MSDN
    Offers help for developers in writing applications using Microsoft products and technologies.
    TechNet
    Offers help for IT professionals using Microsoft products and technologies
    ASP.NET
    The ASP.NET 2.0 site is a portal site for the ASP.NET development community.
    Channel 9
    Channel 9 is a Microsoft discussion forum used to promote conversations among Microsoft’s customers.
    CodePlex
    CodePlex is Microsoft’s open source project hosting web site.
    XML Downloads
    This page provides downloads for building XML applications using Microsoft technologies.

    Phase Out Schedule
    The GotDotNet phase out will be carried out in phases according the following timetable:


    Target Date Areas to be phased out
    February 20 Partners, Resource Center, Microsoft Tools
    March 20 Private workspaces, Team pages, Message Boards
    June 19 Workspaces
    By end of July 2007 CodeGallery (projected date)
    Schedule update in Fall 2007 User Samples (date TBD)

    06 Jun 2007

    如何在Web App Project 或者 Web Site Project的App_Code 内使用 Profile/ProfileCommon

    在 web site project 内 可以很方便的使用 Profile/ProfileCommon 来 访问我们在web.config 的profile节内定义的properties , 并且有很爽的 intellisense
    然而在Web App Project或者Web Site Project的App_Code内使用的时候 编译都通不过的,因为 Profile 是 web site project 模型 在页面 执行时候创建在HttpContext的,Web Site Project 或者App_Code编译的时候还没有页面实例呢,何谈HttpContext, 当然无法使用了

    引用scottgu的原话解释“This is supported because with the VS 2005 Web Site Project option Visual Studio is dynamically creating and adding a "ProfileCommon" class named "Profile" into every code-behind instance”,那么怎么办呢 scottgu 支招------“VS 2005 Web Application Projects don't automatically support generating a strongly-typed Profile class proxy. However, you can use this free download to automatically keep your own proxy class in sync with the profile configuration”。

    我们可以到 gotdotnet 上下载这个 addin  安装,经我测试 这个东西装在中文VS2005 SP1 上右键不会出现菜单(只会出现在外部程序管理器内,看的到用不成,不开心)。
    好在他有源码的,我们用他的源码 找到 大概 40行上下
    string toolsMenuName ;定义部分
    直接 string toolsMenuName = "工具"; 然后下面的 try catch 注释掉----编译---然后把dll文件
    替换到 C:\Documents and Settings\武眉博\My Documents\Visual Studio 2005\AddIns
    就可以用了(原因可能是他的资源文件有问题)
    接下来按照readme使用吧。
    ==================================================
    To use the generator right click on web.config in a Web Application Project and
    select "Generate WebProfile."  This will create a WebProfile class in your
    project based on the current profile setting sin Web.Config.  If you make a
    change to your profile setting you need to run the tool again to update the
    WebProfile class.  The WebProfile class is simply a thin wrapper that has
    strongly typed accessors to profile properties.


    To use the web profile class in a page create an accessor like this:


        // C# accessor
        private WebProfile Profile
        {
            get { return new WebProfile(Context.Profile); }
        }


        ' VB accessor
        Private ReadOnly Property Profile() As WebProfile
            Get
                Return New WebProfile(Context.Profile)
            End Get
        End Property


    Then you can use it like this:


        // C# use or accessor
        string s = Profile.MyProperty;
        Profile.MyGroup.MyProperty = "value";


        ' VB use of accessor
        Dim prop As String = Profile.MyProperty
        Profile.MyGroup.MyProperty = "value"


    You can also access the current profile using the static Current property
    like this:


        // C# use of Current property
        string s = WebProfile.Current.MyProperty;
        WebProfile.Current.MyGroup.MyProperty = "value";


        // VB use of Current property
        Dim s As String = WebProfile.Current.MyProperty
        WebProfile.Current.MyGroup.MyProperty = "value"
        ========================================================
    如果你用的是Web Site Project 想在App_Code内用Profile那么建议 创建一个WebSiteProject web.config拷贝过去仍然使用这个AddIn生成一个WebProfile.cs拷贝回你的app_code内就可以了(哎,怎么感觉像是说了个废话,还不如直接用Web App Project呢)
    OK,就这么几步了。记在这里希望对朋友们有用,睡觉了。

    参考资料: http://webproject.scottgu.com/CSharp/migration2/migration2.aspx

    06 Jun 2007

    如何在Web App Project 或者 Web Site Project的App_Code 内使用 Profile/ProfileCommon

    在 web site project 内 可以很方便的使用 Profile/ProfileCommon 来 访问我们在web.config 的profile节内定义的properties , 并且有很爽的 intellisense
    然而在Web App Project或者Web Site Project的App_Code内使用的时候 编译都通不过的,因为 Profile 是 web site project 模型 在页面 执行时候创建在HttpContext的,Web Site Project 或者App_Code编译的时候还没有页面实例呢,何谈HttpContext, 当然无法使用了

    引用scottgu的原话解释“This is supported because with the VS 2005 Web Site Project option Visual Studio is dynamically creating and adding a "ProfileCommon" class named "Profile" into every code-behind instance”,那么怎么办呢 scottgu 支招------“VS 2005 Web Application Projects don't automatically support generating a strongly-typed Profile class proxy. However, you can use this free download to automatically keep your own proxy class in sync with the profile configuration”。

    我们可以到 gotdotnet 上下载这个 addin  安装,经我测试 这个东西装在中文VS2005 SP1 上右键不会出现菜单(只会出现在外部程序管理器内,看的到用不成,不开心)。
    好在他有源码的,我们用他的源码 找到 大概 40行上下
    string toolsMenuName ;定义部分
    直接 string toolsMenuName = "工具"; 然后下面的 try catch 注释掉----编译---然后把dll文件
    替换到 C:\Documents and Settings\武眉博\My Documents\Visual Studio 2005\AddIns
    就可以用了(原因可能是他的资源文件有问题)
    接下来按照readme使用吧。
    ==================================================
    To use the generator right click on web.config in a Web Application Project and
    select "Generate WebProfile."  This will create a WebProfile class in your
    project based on the current profile setting sin Web.Config.  If you make a
    change to your profile setting you need to run the tool again to update the
    WebProfile class.  The WebProfile class is simply a thin wrapper that has
    strongly typed accessors to profile properties.


    To use the web profile class in a page create an accessor like this:


        // C# accessor
        private WebProfile Profile
        {
            get { return new WebProfile(Context.Profile); }
        }


        ' VB accessor
        Private ReadOnly Property Profile() As WebProfile
            Get
                Return New WebProfile(Context.Profile)
            End Get
        End Property


    Then you can use it like this:


        // C# use or accessor
        string s = Profile.MyProperty;
        Profile.MyGroup.MyProperty = "value";


        ' VB use of accessor
        Dim prop As String = Profile.MyProperty
        Profile.MyGroup.MyProperty = "value"


    You can also access the current profile using the static Current property
    like this:


        // C# use of Current property
        string s = WebProfile.Current.MyProperty;
        WebProfile.Current.MyGroup.MyProperty = "value";


        // VB use of Current property
        Dim s As String = WebProfile.Current.MyProperty
        WebProfile.Current.MyGroup.MyProperty = "value"
        ========================================================
    如果你用的是Web Site Project 想在App_Code内用Profile那么建议 创建一个WebSiteProject web.config拷贝过去仍然使用这个AddIn生成一个WebProfile.cs拷贝回你的app_code内就可以了(哎,怎么感觉像是说了个废话,还不如直接用Web App Project呢)
    OK,就这么几步了。记在这里希望对朋友们有用,睡觉了。

    参考资料: http://webproject.scottgu.com/CSharp/migration2/migration2.aspx