博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

asp.net组件(6)合理使用Events提高性能

Posted on 2007-12-19 17:15  a-peng  阅读(381)  评论(0编辑  收藏  举报
在asp.net组件(5)中有一个事件,我们会其创建一个委托.

那现在的需求是,一个控件中有好多个事件.比如DataList中就有好多个事件,
现在我们夸大一下我们的需求.如果这个控件有1000个事件来说明性能的重要性.
using System;
using System.Web.UI;

namespace WebComponent
{
    [ToolboxData(
@"<{0}:PostBackComponent2 runat='server'></{0}:PostBackComponent2>")]
    
public class PostBackComponent2 : Control, IPostBackEventHandler
    
{
        
//未优化
        private event EventHandler _event1 = null;
        
public event EventHandler Event1
        
{
            add
            
{
                _event1 
+= value;
            }

            remove
            
{
                _event1 
-= value;
            }

        }


        
private event EventHandler _event2 = null;
        
public event EventHandler Event2
        
{
            add
            
{
                _event2 
+= value;
            }

            remove
            
{
                _event2 
-= value;
            }

        }


        
protected void OnEvent1(EventArgs e)
        
{
            
if (_event1 != null)
            
{
                _event1(
this, e);
            }

        }


        
protected void OnEvent2(EventArgs e)
        
{
            
if (_event2 != null)
            
{
                _event2(
this, e);
            }

        }


        
// 实现RaisePostBackEvent方法,处理回发事件
        public void RaisePostBackEvent(string eventArgument)
        
{
            OnEvent1(
new EventArgs());
            OnEvent2(
new EventArgs());
        }


        
protected override void Render(HtmlTextWriter writer)
        
{
            writer.Write(
"<input type='submit' name='" + this.UniqueID + "' value='回发' />");
        }

}
使用这种方式声明1000个事件._event1->_event1000

对象创建初期就会点占用1000个event变量的内在空间.

当我们在一个页面使用了1次该控件时,那么这样我们消耗1000个event
当我们在一个页面使用了3次该控件时,那么这样我们消耗3000个event
这是不可想象的.

所以我们有必要对其优化.

using System;
using System.Web.UI;

namespace WebComponent
{
    [ToolboxData(
@"<{0}:PostBackComponent2 runat='server'></{0}:PostBackComponent2>")]
    
public class PostBackComponent2 : Control, IPostBackEventHandler
    
{        
        
//优化1
        private System.Collections.Hashtable _eventList = new System.Collections.Hashtable();
       
        
private static object _eventKey1 = new object();
        
public event EventHandler Event1
        
{
            add
            
{
                _eventList.Add(_eventKey1, value);
            }

            remove
            
{
                _eventList.Remove(_eventKey1);
            }

        }


        
private static object _eventKey2 = new object();
        
public event EventHandler Event2
        
{
            add
            
{
                _eventList.Add(_eventKey2, value);
            }

            remove
            
{
                _eventList.Remove(_eventKey2);
            }

        }


        
protected void OnEvent1(EventArgs e)
        
{
            EventHandler event1Delegate 
= (EventHandler)_eventList[_eventKey1];
            
if (event1Delegate != null)
            
{
                event1Delegate(
this, e);
            }

        }


        
protected void OnEvent2(EventArgs e)
        
{
            EventHandler event2Delegate 
= (EventHandler)_eventList[_eventKey2];
            
if (event2Delegate != null)
            
{
                event2Delegate(
this, e);
            }

        }


        
// 实现RaisePostBackEvent方法,处理回发事件
        public void RaisePostBackEvent(string eventArgument)
        
{
            OnEvent1(
new EventArgs());
            OnEvent2(
new EventArgs());
        }


        
protected override void Render(HtmlTextWriter writer)
        
{
            writer.Write(
"<input type='submit' name='" + this.UniqueID + "' value='回发' />");
        }

}

使用这种方式声明1000个static object从 _eventKey1->_eventKey1000

对象创建初期我们占用了1000个object变量的内在空间和一个Hashtable.
object的消耗要比event的消耗少很多.

当我们在一个页面使用了1次该控件时,那么这样我们消耗1000个object + 1个Hashtable
当我们在一个页面使用了3次该控件时,那么这样我们消耗1000个object + 1个Hashtable
这也是为什么用static object

asp.net中提供了Events 也就是委托列表.System.ComponentModel.EventHandlerList类型.

using System;
using System.Web.UI;

namespace WebComponent
{
    [ToolboxData(
@"<{0}:PostBackComponent2 runat='server'></{0}:PostBackComponent2>")]
    
public class PostBackComponent2 : Control, IPostBackEventHandler
    
{
        
//优化2
        
        
private static object _eventKey1 = new object();
        
public event EventHandler Event1
        
{
            add
            
{
                Events.AddHandler(_eventKey1, value);
            }

            remove
            
{
                Events.RemoveHandler(_eventKey1, value);
            }

        }


        
private static object _eventKey2 = new object();
        
public event EventHandler Event2
        
{
            add
            
{
                Events.AddHandler(_eventKey2, value);
            }

            remove
            
{
                Events.RemoveHandler(_eventKey2, value);
            }

        }


        
protected void OnEvent1(EventArgs e)
        
{
            EventHandler event1Delegate 
= (EventHandler)Events[_eventKey1];
            
if (event1Delegate != null)
            
{
                event1Delegate(
this, e);
            }

        }


        
protected void OnEvent2(EventArgs e)
        
{
            EventHandler event2Delegate 
= (EventHandler)Events[_eventKey2];
            
if (event2Delegate != null)
            
{
                event2Delegate(
this, e);
            }

        }


        
// 实现RaisePostBackEvent方法,处理回发事件
        public void RaisePostBackEvent(string eventArgument)
        
{
            OnEvent1(
new EventArgs());
            OnEvent2(
new EventArgs());
        }


        
protected override void Render(HtmlTextWriter writer)
        
{
            writer.Write(
"<input type='submit' name='" + this.UniqueID + "' value='回发' />");
        }

}

到这里就说完了.
在啰嗦一下,怎么使用它.
新建一个网页
拉入控件,为其添加事件委托.

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Ch06 : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        
this.PostBackComponent2_1.Event1 += new EventHandler(PostBackComponent2_1_Event1);
        
this.PostBackComponent2_1.Event2 += new EventHandler(PostBackComponent2_1_Event2);
    }


    
protected void PostBackComponent2_1_Event1(object sender, EventArgs e)
    
{
        Response.Write(
"<script language='javascript'>alert('PostBackComponent2_1_Event1');</script>");
    }


    
protected void PostBackComponent2_1_Event2(object sender, EventArgs e)
    
{
        Response.Write(
"<script language='javascript'>alert('PostBackComponent2_1_Event2');</script>");
    }



}