You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么.NET中递归绑定gridview会引发堆栈溢出问题?

堆栈溢出的根本原因是触发了数据绑定的无限递归循环,具体调用链如下:

  • 页面首次加载(IsPostBack为false),GridView完成第一次数据绑定,触发DataBound事件
  • 执行DBG_DataBound方法,命中!IsPostBack判断分支,调用SetPage方法
  • SetPage方法修改DBG.PageIndex属性,对于已经绑定了数据源的GridView控件,修改分页索引会自动触发控件重新执行数据绑定
  • 重新绑定完成后再次触发DataBound事件,注意同一个请求生命周期内IsPostBack的值不会发生变化,所以仍然会命中!IsPostBack分支,再次调用SetPage
  • 上述流程无限循环,直到线程栈空间耗尽,抛出堆栈溢出错误。

附带的潜在问题

你在OnLoad方法中每次页面生命周期执行时,都会给LinqDS和DBG的事件追加新的匿名委托:

LinqDS.Selecting += delegate { ... };
LinqDS.Selected += delegate { ... };
DBG.DataBinding += delegate { ... };
DBG.DataBound += delegate { ... };

这些匿名委托不会被自动注销,同一次请求内如果触发多次绑定,这些委托会重复执行,多次请求后也会累积内存占用问题,建议将事件绑定逻辑移到if(!IsPostBack)分支内,或者在Page_Init阶段只绑定一次。


修复方案

修改DBG_DataBound的逻辑,只有当当前页索引和要设置的页索引不一致的时候才执行修改,避免重复触发绑定:

protected void DBG_DataBound(object sender, EventArgs e)
{
    PageControls.Visible = DBG.PageCount > 1;

    if (!IsPostBack)
    {
        var key = GridKey;
        var targetPage = Session[key] != null ? (int)Session[key] : 0;
        // 仅当目标页和当前页不一致时才修改
        if (DBG.PageIndex != targetPage)
        {
            SetPage(targetPage);
        }
    }
}

内容的提问来源于stack exchange,提问作者Shibashish Mohanty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:09:00