System.IndexOutOfRangeException 神秘地从 System.Collections.Generic.List.Add(T item) 抛出

问题描述 投票:0回答:1

我一直在努力通过以下堆栈跟踪(故意缩短)找出异常的原因:

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.:我不知道这是否有任何明显的相关性,但是这个问题很少发生,并且只发生在我们的生产服务器上,因此很难在本地重现。我还没有成功,但是我有办法在生产服务器上重现它。

c# .net stack-trace outofrangeexception sqlhelper
1个回答
0
投票

我终于明白了这一点。事实证明问题出在 EndLog() 中。由于某种原因,它在堆栈跟踪中被跳过。也许当发布版本完成时,函数 EndLog() 由于某种原因被内联(我仍然不确定为什么)。但是有一个列表同时被 2 个线程访问。我在“添加”操作中添加了一个锁,它解决了问题。

感谢大家的回答!

© www.soinside.com 2019 - 2024. All rights reserved.