【问题标题】:AutoEventWireup and base.OnLoad(e) Calling Self resulting in Stack OverflowAutoEventWireup 和 base.OnLoad(e) 调用 Self 导致堆栈溢出
【发布时间】:2011-11-17 21:40:29
【问题描述】:

使用 VS2008,C#。当 AutoEventWireup 设置为 true 并且在网络表单中我调用 base.OnLoad(e) 时:

protected void Page_Load(object sender, EventArgs e)
{
    base.OnLoad(e);
}

base.OnLoad(e) 最终调用Page_Load(调用自身)。这最终导致堆栈溢出错误。我已经能够通过将 AutoEventWireup 设置为 false 并覆盖 OnLoad 来解决它:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
}

这按我的预期工作(没有堆栈溢出)。但是谁能解释为什么在第一个示例中base.OnLoad(e) 调用相同的加载事件(调用自身)而不是调用基类中的OnLoad 事件(System.Web.UI.Page)?

【问题讨论】:

    标签: c# asp.net autoeventwireup


    【解决方案1】:

    Page.OnLoad 里面有如下伪代码

    protected virtual void OnLoad() {
        // some stuff
    
        if (Load != null)
            Load(this, new EventArgs());
    }
    

    如果你重写OnLoad 函数,会发生什么:你的OnLoad 发生了,然后它调用base.OnLoad(),然后调用(空)Load 事件。

    如果您实现Load 事件并调用base.OnLoad(),会发生以下情况:base.OnLoad() 调用Load 事件。然后Load 事件调用base.OnLoad()。然后,base.OnLoad() 调用Load 事件。剩下的就是,正如他们所说,要理解递归,你必须首先理解递归。

    希望我说清楚了。

    【讨论】:

    • 在你的答案、BC 的答案和在 Visual Studio 中测试你的答案之间,我终于明白了。谢谢。
    【解决方案2】:

    OnLoad 不调用自身,它调用 Load 事件。 Page.OnLoad 方法仅包装对附加事件的调用。不应从 Load 事件处理程序调用 base.OnLoad,否则会导致无限循环。

    【讨论】:

    • 但是为什么base.OnLoad(e)没有调用基类的Load事件呢?
    • 确实如此。这就是为什么处理 Load 事件并调用 base.OnLoad 会导致无限循环。
    • 但是在第二个示例中,我覆盖了 OnLoad 事件(并且 AutoEventWireup 为假),base.OnLoad(e) 也在那里被调用,没有任何无限循环。我在第二个示例中的 OnLoad 处理程序是否也处理加载事件......为什么在这种情况下没有无限循环?
    • 那是因为您没有使用 Page_Load 处理 Load 事件。您混淆了 OnLoad 和 Page_Load - 一个是虚拟方法,一个是事件处理程序。当您覆盖 OnLoad 并调用 base.OnLoad 时,base.OnLoad 然后调用 Load 事件,该事件不存在!没有循环!
    • 现在很有意义。你是对的,我错误地将 OnLoad 覆盖视为事件处理程序,但事实并非如此。谢谢你的耐心:)
    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 2015-05-21
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 2017-06-04
    相关资源
    最近更新 更多