如何为SqlHelper.FillDataset设置超时解决30秒超时异常?
问题描述
以下代码执行存储过程时,尽管设置了command.CommandTimeout = 1000,但依然会在30秒(默认超时时间)后抛出异常。手动在SQL Server中执行该存储过程耗时约1分15秒,此前代码运行正常,修改某表列数据类型后存储过程执行时间变长,导致超时异常。
private static abc Getabc(string a, int b, int c) { var d = new abc(); try { var command = new SqlCommand("helloworld"); command.CommandTimeout = 1000; SqlHelper.FillDataset(Config.ConnectionString, CommandType.StoredProcedure,"helloworld", d, new[] {"cat", "dog"}, new[] { new SqlParameter("@bb", b), new SqlParameter("@aa", a), new SqlParameter("@cc", c), }); } catch (Exception e) { Console.WriteLine(e.Message); } return data; }
问题原因
你创建的SqlCommand对象完全没有被SqlHelper.FillDataset方法使用——这个方法会根据你传入的连接字符串、命令文本等参数内部重新创建一个SqlCommand实例,所以你手动设置的CommandTimeout根本不会生效,最终用的是SqlCommand的默认超时(30秒)。
解决方案
方案1:使用支持传入SqlCommand的SqlHelper.FillDataset重载
如果你的SqlHelper类提供了接受SqlCommand对象作为参数的重载版本,直接传入配置好超时的命令对象即可:
private static abc Getabc(string a, int b, int c) { var d = new abc(); try { using (var connection = new SqlConnection(Config.ConnectionString)) { var command = new SqlCommand("helloworld", connection); command.CommandType = CommandType.StoredProcedure; command.CommandTimeout = 1000; command.Parameters.AddRange(new[] { new SqlParameter("@bb", b), new SqlParameter("@aa", a), new SqlParameter("@cc", c), }); SqlHelper.FillDataset(command, d, new[] {"cat", "dog"}); } } catch (Exception e) { Console.WriteLine(e.Message); } return d; // 注:原代码return的是未定义的data,此处修正为d }
方案2:手动实现Dataset填充逻辑(不依赖SqlHelper)
如果SqlHelper没有合适的重载,直接自己写数据库操作逻辑,完全控制命令参数:
private static abc Getabc(string a, int b, int c) { var d = new abc(); try { using (var connection = new SqlConnection(Config.ConnectionString)) { connection.Open(); var command = new SqlCommand("helloworld", connection); command.CommandType = CommandType.StoredProcedure; command.CommandTimeout = 1000; command.Parameters.AddRange(new[] { new SqlParameter("@bb", b), new SqlParameter("@aa", a), new SqlParameter("@cc", c), }); using (var adapter = new SqlDataAdapter(command)) { adapter.Fill(d, "cat"); adapter.Fill(d, "dog"); } } } catch (Exception e) { Console.WriteLine(e.Message); } return d; }
额外优化建议(从根源解决超时)
延长超时只是临时方案,存储过程执行变慢的核心原因是修改列类型后可能出现:
- 表统计信息过期,SQL Server生成低效执行计划
- 参数嗅探问题,导致执行计划不匹配当前数据分布
可以执行以下操作优化:
- 更新表统计信息:
UPDATE STATISTICS [你的表名]; - 重新生成存储过程执行计划:
EXEC sp_recompile N'helloworld'; - 检查存储过程内部查询,添加合适索引或调整查询逻辑
内容的提问来源于stack exchange,提问作者Flying Nimbus
相关产品推荐
相关产品推荐

