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

Page_Load调用方法触发adapter.fill() StackOverflowException,其他场景正常

问题:Page_Load调用数据绑定方法时触发StackOverflowException

在DropDownList的SelectedIndexChanged事件中调用数据绑定方法完全正常:

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
  int machineid = int.Parse(DropDownList1.SelectedValue);
  try { 
  connection.Open();
  EquimentBind(machineid);
      
  }
 
  finally { connection.Close(); }

}

但在Page_Load中通过URL传入ID调用时,总会在sd.Fill(dt1)步骤抛出StackOverflowException:

protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
    string station_id = Request.QueryString["station_id"];

    if (station_id != null)
    {
      DropDownList1.Visible = false;
      int machineid = int.Parse(station_id);
      try
      {
        if (connection.State != ConnectionState.Open)
        {
          connection.Open();
        }
        EquimentBind(machineid);
       
      }
      finally { connection.Close(); }
    }   
    else
    {
      try
      {
        if (connection.State != ConnectionState.Open) { connection.Open(); }
        SqlDataAdapter adapter = //My sql command
        DataTable stalist = new DataTable();
        adapter.Fill(stalist);
        DropDownList1.DataSource = stalist;
        DropDownList1.DataTextField = "name";
        DropDownList1.DataValueField = "Id";
        DropDownList1.DataBind();
      }
      finally { connection.Close(); }
      DropDownList1.SelectedValue = Convert.ToString('0');
    }
  }
}

数据绑定方法代码:

protected void EquimentBind(int machineid)
{
  SqlCommand Sqlcommand = // my sql command
  SqlCommand command = Sqlcommand;
  SqlDataAdapter sd = new SqlDataAdapter(command);
  DataTable dt1 = new DataTable();
  sd.Fill(dt1);
  GV_Equipments.DataSource = dt1;
  GV_Equipments.DataBind();
  command.ExecuteNonQuery();
  dt1.Clear();
}

问题分析与修复方案

核心问题1:全局connection对象复用导致的异常

你复用了同一个全局SqlConnection对象,ADO.NET的连接对象设计为单次使用即销毁,全局复用容易引发连接状态紊乱,甚至触发内部循环重试逻辑,最终导致栈溢出。

核心问题2:EquimentBind方法的冗余操作

  • command.ExecuteNonQuery()完全多余:SqlDataAdapter.Fill()已经执行了查询命令获取数据,重复调用无意义,还可能引发额外的执行逻辑。
  • dt1.Clear()属于无效操作:绑定完成后DataTable会被GC自动回收,手动清空反而可能引发意外。

核心问题3:循环调用触发栈溢出

StackOverflowException本质是无限循环/递归导致的,需检查GV_Equipments的绑定相关事件(如RowDataBound),确保没有在事件中再次调用EquimentBind或触发页面重新加载的代码。

具体修复步骤

  1. 重构连接使用逻辑,使用using自动管理生命周期
protected void EquimentBind(int machineid)
{
    // 从Web.config读取连接字符串,替换为你实际的配置键
    string connStr = ConfigurationManager.ConnectionStrings["YourConnString"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(connStr))
    {
        // 替换为你的实际查询SQL
        string sql = "SELECT * FROM YourEquipmentTable WHERE MachineId = @MachineId";
        using (SqlCommand command = new SqlCommand(sql, conn))
        {
            command.Parameters.AddWithValue("@MachineId", machineid);
            SqlDataAdapter sd = new SqlDataAdapter(command);
            DataTable dt1 = new DataTable();
            sd.Fill(dt1);
            GV_Equipments.DataSource = dt1;
            GV_Equipments.DataBind();
        }
    }
}
  1. 修改Page_Load中的调用逻辑
    移除全局connection依赖,直接调用重构后的方法:
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string station_id = Request.QueryString["station_id"];
        if (station_id != null)
        {
            DropDownList1.Visible = false;
            int machineid = int.Parse(station_id);
            EquimentBind(machineid);
        }   
        else
        {
            string connStr = ConfigurationManager.ConnectionStrings["YourConnString"].ConnectionString;
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                // 替换为你的下拉列表查询SQL
                string sql = "SELECT Id, name FROM YourStationTable";
                SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
                DataTable stalist = new DataTable();
                adapter.Fill(stalist);
                DropDownList1.DataSource = stalist;
                DropDownList1.DataTextField = "name";
                DropDownList1.DataValueField = "Id";
                DropDownList1.DataBind();
            }
            // 修正SelectedValue赋值:Convert.ToString('0')会得到ASCII码"48",直接用字符串"0"
            DropDownList1.SelectedValue = "0";
        }
    }
}
  1. 检查GridView事件绑定
    确认GV_Equipments的所有事件(如RowDataBound、RowCommand)中没有再次调用EquimentBind或触发页面回发/重载的代码,避免循环调用。

内容的提问来源于stack exchange,提问作者Hua Deng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:53:14