我一直在努力通过以下堆栈跟踪(故意缩短)找出异常的原因:
System.IndexOutOfRangeException:索引超出了数组的范围。在 System.Collections.Generic.List1.Add(T 项) 在 PPM.Dal.Entities.Code.SqlHelper.ExecuteEntityArray[TEntity](CommandType commandType、String commandText、String connectionString、Nullable1 commandTimeout、DynamicParameters 参数、布尔 useTransaction)
PPM.Dal.Entities.Code.SqlHelper.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 ex”,否则这是不可能的。这里我们有一个裸露的“抛出”,它应该维护异常的原始堆栈跟踪。
有人知道这个方法如何抛出异常吗?
P.S.:我不知道这是否有任何明显的相关性,但是这个问题很少发生,并且只发生在我们的生产服务器上,因此很难在本地重现。我还没有成功,但是我有办法在生产服务器上重现它。
我终于明白了这一点。事实证明问题出在 EndLog() 中。由于某种原因,它在堆栈跟踪中被跳过。也许当发布版本完成时,函数 EndLog() 由于某种原因被内联(我仍然不确定为什么)。但是有一个列表同时被 2 个线程访问。我在“添加”操作中添加了一个锁,它解决了问题。
感谢大家的回答!