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或触发页面重新加载的代码。
具体修复步骤
- 重构连接使用逻辑,使用
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(); } } }
- 修改
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"; } } }
- 检查GridView事件绑定
确认GV_Equipments的所有事件(如RowDataBound、RowCommand)中没有再次调用EquimentBind或触发页面回发/重载的代码,避免循环调用。
内容的提问来源于stack exchange,提问作者Hua Deng
相关产品推荐
相关产品推荐

