求助:System.IndexOutOfRangeException在List.Add中莫名抛出的原因排查
异常排查:未调用List.Add()却抛出IndexOutOfRangeException
问题背景
简化后的异常堆栈跟踪:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Generic.List1.Add(T item) at PPM.Dal.Entities.Code.SqlHelper.ExecuteEntityArray[TEntity](CommandType commandType, String commandText, String connectionString, Nullable1 commandTimeout, DynamicParameters parameters, Boolean useTransaction)
对应的ExecuteEntityArray方法代码:
private static TEntity[] ExecuteEntityArray<TEntity>(CommandType commandType, string commandText, string connectionString, int? commandTimeout, DynamicParameters parameters, bool useTransaction) where TEntity : class, new() { var sqlAction = StartLog(commandType, commandText, null, parameters); try { TEntity[] result; var transaction = CurrentTransaction; if (useTransaction && transaction != null && (connectionString == null || transaction.ConnectionString == connectionString)) { // Use the existing transaction to execute the query result = transaction.SqlConnection.Query<TEntity>(sql: commandText, param: parameters, transaction: transaction.SqlTransaction, commandType: commandType, commandTimeout: commandTimeout).ToArray(); } else { if (connectionString == null) { connectionString = ConnectionStringData; } using (var sqlConnection = new SqlConnection(connectionString)) { result = sqlConnection.Query<TEntity>(sql: commandText, param: parameters, commandType: commandType, commandTimeout: commandTimeout).ToArray(); } } EndLog(sqlAction, null); return result; } catch (SqlException ex) { EndLog(sqlAction, ex); HandleSqlExceptions(ex, null); throw; } catch (Exception ex) { EndLog(sqlAction, ex); throw; } }
困惑点:方法中并未直接调用List.Add(),但堆栈明确指向该方法内抛出此异常;确认使用无参数throw保留了原始堆栈,排除堆栈错误的可能。
补充:该问题仅在生产服务器偶发,本地难以复现,但已找到生产环境复现方式。
可能的原因分析
- Dapper内部实现调用:
Query<TEntity>方法底层会用List<TEntity>存储查询结果,最终通过ToArray()转换为数组。堆栈中的List.Add()是Dapper内部执行时触发的,并非你的代码直接调用。 - 实体类(TEntity)存在不安全并发操作:如果TEntity的无参构造函数或属性setter中,有操作静态List的逻辑,生产环境高并发场景下,多个线程同时修改这个静态List就会触发
IndexOutOfRangeException。此时异常会在Dapper实例化实体、赋值属性的过程中抛出,堆栈会显示为List.Add()被你的ExecuteEntityArray方法调用。 - Dapper版本存在并发bug:旧版本的Dapper在处理查询结果映射时,若存在并发修改内部缓存(比如实体映射信息)的情况,可能导致内部List操作异常。
- 查询结果与实体映射冲突:如果查询返回的列存在重复名称、或者实体属性的映射逻辑有异常,可能导致Dapper在填充实体时触发意外的集合操作,进而引发异常。
排查建议
- 检查TEntity的无参构造函数和所有属性的setter方法,确认是否有操作静态集合的代码,若有则替换为线程安全集合(比如
ConcurrentBag)或添加锁控制。 - 升级Dapper到最新稳定版本,验证是否是旧版本的已知bug导致。
- 在生产复现场景中,捕获更详细的异常上下文(比如当前执行的SQL语句、参数值、对应的TEntity类型),缩小排查范围。
内容的提问来源于stack exchange,提问作者Borislav-K
相关产品推荐
相关产品推荐

