System.IndexOutOfRangeException таинственным образом выброшено из System.Collections.Generic.List.Add(T item)

Я изо всех сил пытался выяснить причину исключения с помощью следующей трассировки стека (намеренно сокращенной):

System.IndexOutOfRangeException: индекс вышел за пределы массива. в System.Collections.Generic.List1.Add(T item) в 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.: Я не знаю, имеет ли это какое-либо очевидное значение, но проблема возникает довольно редко и только на наших рабочих серверах, поэтому ее довольно сложно воспроизвести локально. Мне пока не удалось, но у меня есть способ воспроизвести это на рабочем сервере.

Может быть, что-то вроде многопоточного параллелизма? Возможно, CurrentTransaction одновременно используется из разных потоков.

Uwe Keim 17.04.2024 15:04

Такое ощущение, что здесь не хватает какой-то трассировки стека — я предполагаю, что это происходит из-за каких-то внутренних компонентов Query<T>() или ToArray().

Martin Costello 17.04.2024 15:07

Пробовали ли вы зарегистрировать исключение и получить ПОЛНУЮ трассировку стека? Я думаю, что что-то происходит внутри Query, или Query возвращает что-то, с чем ToArray не может работать. Хотя напиши мне, когда сделаешь

John Demetriou 17.04.2024 15:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я наконец понял это. Оказывается, проблема была в EndLog(). По какой-то причине он был пропущен в трассировке стека. Возможно, когда сборка Release завершена, функция EndLog() была встроена по какой-то причине (я до сих пор не понимаю, почему). Но был список, к которому обращались сразу 2 потока. Я добавил блокировку к операции добавления, и это устранило проблему.

Спасибо за все ответы!

Другие вопросы по теме