有一个空页面,运行时动态从配置文件中装载用户控件(.ascx)。配置文件:<xml ...>
    <UserControl>
         <Name>Header.ascx</Name>
    </UserControl>
    <UserControl>
         <Name>Login.ascx</Name>
    </UserControl>
    <UserControl>
         <Name>News.ascx</Name>
    </UserControl>
    <UserControl>
         <Name>Footer.ascx</Name>
    </UserControl>
    ......
页面运行时:
Page_Load(object sender, EventAge e)
{
    DataSet ds = new DataSet();    ds.ReadXml("配置文件");    foreach(DataRow dr in ds.Tables[0].Rows)
    {
        this.Form1.LoadControl(dr["Name"].ToString());
    }
}---------------------------------这样的性能肯定有问题,请大虾们各抒己见,如何提高性能,谢谢!!注:以上代码是故意简化的。只是描述清楚我的问题。

解决方案 »

  1.   

    我先问楼主:Form1.LoadControl()会做什么动作?
      

  2.   

    TemplateControl.LoadControl Method (String)Loads a Control object from a file based on a specified virtual path. If the control supports caching, the object returned from the LoadControl method is not actually a Control object; rather, it is a PartialCachingControl object. If the virtualPath parameter is relative, the path of the loaded control is relative to the path of the TemplateControl.When you load a control into a container control, the container raises all of the added control's events until it has caught up to the current event. However, the added control does not catch up with postback data processing. For an added control to participate in postback data processing, including validation, the control must be added in the Init event rather than in the Load event.
      

  3.   

    xhtmldivcss 你好:    LoadControl 装载 Web用户控件到页面 (.ascx)。
      

  4.   

    xhtmldivcss 你好,发生你那个错误,是 ascx 文件不存在,装载控件不成功,
    或者是路径指错了。
      

  5.   

    PartialCachingControl ClassCreated when a user control (.ascx file) is specified for output caching, using either the @ OutputCache page directive or the PartialCachingAttribute attribute, and the user control is inserted into a page's control hierarchy by dynamically loading the user control with the TemplateControl..::.LoadControl method. Page and control developers cannot use the PartialCachingControl class directly. ASP.NET creates an instance of the PartialCachingControl class to wrap a user control (.ascx file) when a dynamically loaded user control enables output caching. You can enable output caching for a user control using either the @ OutputCache page directive or the PartialCachingAttribute attribute. You add a user control to a page programmatically by calling the TemplateControl..::.LoadControl method. 看到这里至少说明可以指定UserControl的OutputCache来一定程度上提升性能。
      

  6.   

    还有就是如果UserControl想利用参与ViewState的Load()和Save()过程,那么最好把LoadControl()的过程放在Page.Init()方法里。
      

  7.   

    还有个建议就是XmlDataSource控件默认支持Caching,能否利用XmlDataSource来读取UserControl名称列表,一定程度上提升些性能?
      

  8.   

    看不出什么性能问题,要是我可能会用javascript+AJAX来加载页面
      

  9.   

    随便聊什么都可以吧?我正在测试在Page_Init和Page_Load里加载UserControl,是不是像书里说的那样有区别。
      

  10.   

    我得问楼主了。一般MSDN上的范例里都是在Page_Init里加载控件。如:
    protected void Page_Init(object sender, EventArgs e)
    {
            Control ctrl = Page.LoadControl("~/UserControls/MyUC1.ascx");
            uc1 = (UserControls_MyUC1)ctrl;        PlaceHolder1.Controls.Add(uc1);
    }我发现在Page_Load里加载好像也没什么区另啊。那么:
    For an added control to participate in postback data processing, including validation, the control must be added in the Init event rather than in the Load event. 这句话应该怎么理解?
      

  11.   

    难道放在 Init 中,PostBack 时,系统不会重新加载,
    而放在 OnLoad 中,因为没有使用 if (!isPostBack)  而每次回传都要加载一次?
      

  12.   

    刚测试了, 放在 Init, OnLoad 中,没有任何区别。都是一样的。都有ViewState 。
      

  13.   

    仅仅是对 xml 文档缓存的就不用说了嘛,这个是肯定的。主要的问题是,每次页面加载,都要加载用户控件,包括回传后。
    对 CPU 的占用比较高。请大家继续啊。
      

  14.   


    通常之所以“动态加载”,往往是因为要根据页面状态来决定加载的具体Ascx。而写死的方式,那种        Control ctrl = Page.LoadControl("~/UserControls/MyUC1.ascx"); 
            uc1 = (UserControls_MyUC1)ctrl; 
            PlaceHolder1.Controls.Add(uc1); 
    其实没有什么实用意义,只能作为一种语法演示而已,完全可以在设计器上把ascx拖入,而无需“写死”代码。真正使用时,往往是:        object content=ViewState["cont"];
            if(content!=null)
            {
               Control ctrl = Page.LoadControl((string)content); 
               ctrl.ID="cont";
               PlaceHolder1.Controls.Add(ctrl); 
            }而且,你所举得的这段代码缺少“要命的”ID属性设置,多余进行类型转换,实在看不出专业应用的痕迹。MSDN中如果有这一段,实在是一个外行写的这一段。
      

  15.   


    别说什么放在 Init 中,就算是你在设计器上设计的aspx页面中写死的控件,例如随便放一个 TextBox 控件,回发时也是重新加载的。只不过它是在 Init 之前。包括你通过鼠标拖动到设计器上的ascx,也是动态加载的。唯一只是它不是你自己写代码手动加载,而是asp.net编译时生成了那段代码。如果说你手动加载控件会明显降低效率,只能是写错了代码,写出多余执行很多无用操作的代码。
      

  16.   

    在对手写的添加子控件代码称作“动态加载”之外,我从来没有把那些写死在aspx等设计页面上的控件叫做“静态”的,我不知道有没有别人这样叫。即使这样叫,也只是从代码书写方式上看起来像是“静态”。页面对象整个是动态的,每当asp.net处理请求时都创建了新的页面实例,而此时页面就要逐一创建控件并放入自己的控件树。没有什么控件是静态的,不论是设计页面上声明的控件还是程序员代码生成的控件都是这样。
      

  17.   

    不论是页面缓存还是片段缓存,都是提高asp.net效率的基本手段。只有缓存生效,才能做到所谓的“静态”,即不去动态生成子控件。所以,缓存是页面部署到生产服务器上时需要启用的最基本的技术,不是什么高级技术。
      

  18.   

    把代码写在init里是为了防止数据二次绑定,在一些特定的情况下。
    我看过专门介绍这个问题的,但实在是没能理解。
    好像书上的意思是,页面第一次加载,会经历n个页面事件;然后回发时,就只会有(n-1)个页面事件;而这剪掉的1个事件就是init事件。
    仅仅是“好像”!!!
    我后来试过一段时间,不得要领,只得做罢了。
      

  19.   


    进行类型转换是为了访问ascx里自定义属性,这种情况还是有的吗?=====================
    再说了,难道没发现
    Control ctrl = Page.LoadControl("~/UserControls/MyUC1.ascx"); 
    uc1 = (UserControls_MyUC1)ctrl; 
    PlaceHolder1.Controls.Add(uc1); 
    它会自定赋ID给动态加载的控件吗?总的来讲,为什么sp1234认为实际上不会有动态加载ascx的需要?就比如根据情况加载或不加载?
      

  20.   


    既然是动态加载ascx,那么无论是在Init,还是Load里加载,都必须在每次的回发中加载一次。这是肯定的。
    主要的问题是在Load里加载时,那是在页面Page Life-cyle的Load ViewState过程结束以后。
    那么,按技术文档里说话这是不“正规”的作法。我仅仅是这方面没想通而已。而不觉得动态加载控件有什么问题。加载时机问题,原理没搞清楚。这才是问题。
      

  21.   


    第一次访问或者后续的Postback,总是会执行Init是吧?这又不是winform,没有什么放在Init就能防止二次绑定的问题。放在Init,还是Load里,涉及到的是ViewState的问题。这里着实让人想不太明白。
    我知道放在Init是为了在LoadViewState之前加载动态控件,也就是说进入Load ViewState这个过程之前把页面的控件树建立好。为什么呢?好像是这里涉及到的页面管理子控件的view state的细节问题。
      

  22.   

    我并没有说没有动态加载ascx的需要,而是说通常没有在Init事件中手写这段代码的需要。因为通常在页面中当要决定动态加载什么,或者不加载时,需要访问页面状态。而Init得不到页面状态,所以应该放在Page_Load或者CreateChildControl()等地方。在Init时加载的很多代码,我们可以看到它对“动态”的体现很少,基本上都可以用直接在设计页面上拖入ascx作为替代,之后可以通过Multiview控件或者ascx的Visible来控制是否显示。
      

  23.   

    我只是从表面上看来说下:
    1.如果你的xml文件很大,读取xml文件及查找某个节点必须要花时间2.foreach(DataRow dr in ds.Tables[0].Rows)  不知你的ds.Tables[0]有多少row,当然如果你的站点访问的用户不多这个可以忽略的.
      

  24.   

    .NET C# 技术 QQ群:3582108.
      

  25.   


    即使你在Page_load事件处理程序中加入控件,asp.net也可以管理好它的viewstate。一种动态控件,是在页面已经进入LoadViewState过程之中,通过FindControl方法(查找控件内部的子控件)调用了EnsureChildControl从而调用了CreateChildControls方法,调用了你写在override的CreateChildControls方法内的代码装入子控件。它的状态数据和Post数据会随后、在页面的page_load开始之前填入。另一种动态控件,就是在page_load中创建控件并放入父控件的Controls集合,它的状态数据和Post数据会在Page_Load完成之后才填入。也就是说asp.net会两次为考虑ViewState才动态创建的子控件处理状态和值,以及记录应该触发的事件。为什么考虑ViewState才动态创建子控件?因为asp.net本来就是支持一个交互设计的嘛。页面上用户应该交互地干很多事,界面变化很多次,然后当用户觉得满意了、可以离开这个页面了,才把一些状态数据提交到数据库里。
      

  26.   

    换句话说,“放在Init还是Load里”只有一点差别,就是后者比前者更灵活。在性能、功能上没有任何差别。asp.net是一个多年拼凑、不断改进而成的架构,页面的控制主流程有着无数的令人眼花缭乱的条件判断分支,就是为了不断应付新的需求又能兼容老的需求而设计的。我相信最早的(asp.net1.1发布之前甚至是最初正式发布asp.net之前的原型)可能没有ViewState,于是将只要有asp.net编译页面时生成的在 FrameworkInitialize 方法中调用代码生成器生成的创建子控件方法,以及提供Init事件,就够了。之后才出现了CreateChildControls机制,到最后发现还是不够才出现了在Load只能给添加控件机制。实际上asp.net1.1与asp.net2.0处理Load添加控件机制不同,前者是将子控件放入页面控件树时立刻处理状态和提交数据、记录事件,而后者是只做标记待到Load整个执行完毕才统一进行。因此有不少asp.net1.1的程序会很“奇妙”地出错,因此一旦使用asp.net2.0编程就不要再去碰asp.net1.1了。一句话,多是进化造成的,在性能、功能上并没有太大区别,最新出现的东西往往会有更好的缓冲等优化措施,而老的做法则可能不再优化了。所以,装载动态控件最好不在Init,也不在CreateChildControl方法,就是简单地在load中进行就可以了。
      

  27.   

    到最后发现还是不够才出现了在Load只能给添加控件机制  -->  到最后发现还是不够才出现了在Load也能添加子控件机制要支持添加子控件,需要自动处理子控件随后自动获得状态、提交值、事件的功能。因此在Load之后并真正不支持添加子控件,虽然你可以写代码去添加,但是状态、提交值、事件等全都不会给子控件自动设置。
      

  28.   

    sp1234,多谢了。
    虽然还是不太明白,不过我看的肯定是1.1的技术文档。
    听你这么一说感觉舒服多了。我突然想到,好多人为什么说asp.net简单呢?简单吗?还是我想得太复杂了。
      

  29.   

    asp.net比winForm的机制要复杂。正因为复杂,并不容易自定义出非常完善的面向特定应用的界面组件。
      

  30.   

    呵呵,有这么多的控件需要加载吗?使用visible会怎么样呢?
      

  31.   

    各位大虾的讨论真实精彩绝伦啊,高度一步一步攀升。谢谢了。
    同感,sp1234、xhtmldivcss 说出了微软对 ASP.NET 的设计理念,让简单应用的人觉得简单无比,而高级应用如“自定义出非常完善的面向特定应用的界面组件”绝不是那么简单的,ASP.NET 的内部构造是一个复杂而庞大的工程啊。
      

  32.   

    初步结论:
    1 哪里加载都还是要加载的。包扩 PostBack 时也是要重新加载的。 加载是不能避免的。
    2 xml 的读取肯定是要缓存和进行一些处理的。
    3 页面缓存、静态页面方法。
    (1) 静态页面不需讨论了,这个肯定是行得通的。-- 当 xml 变化后,第一次访问动态页面时,生成静态页面。以后访问静态页面。
    (2) 页面缓存也是要考虑的。
    -------------大虾们还有没有其他见解呢,欢迎继续讨论。谢谢.
      

  33.   

    看了楼主的代码,好像并不是生成html页面吗?这是动态装载控件而已!
    不知道该讨论很么?
      

  34.   


    是啊,这里并不是讨论生成 html.是讨论动态加载控件,能否有提升性能的空间。