Исключение «Коллекция была изменена», когда она не была - PullRequest
3 голосов
/ 21 апреля 2019

Я получаю это исключение с этим кодом и не могу понять, почему

private static void LoopBTCtx()
{
    Task.Factory.StartNew(async () =>
    {
        while (true)
        {
            try
            {
                Thread.Sleep((int)TimeSpan.FromSeconds(10).TotalMilliseconds);

                List<(string, SocketMessage, int)> _btcTX = btcTX;

                foreach (var tx in btcTX)
                {
                    int newConfirmations = GetBTCtxConfirmations(tx.Item1);

                    if (tx.Item3 != newConfirmations)
                    {
                        _btcTX.Remove(tx);

                        if (newConfirmations < 6)
                        {
                            _btcTX.Add((tx.Item1, tx.Item2, newConfirmations));
                        }

                        await tx.Item2.Channel.SendMessageAsync($"{tx.Item2.Author.Mention}, ``{tx.Item1}`` now has **{newConfirmations}**/6 confirmation{(newConfirmations != 1 ? "s" : null)}.");
                    }
                }

                btcTX = _btcTX;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    });
}

Выдается после обработки первого элемента списка (foreach)

Строка исключения из трассировки стека - это строка, содержащая foreach (var tx in btcTX)

Я пытался использовать 2 разных списка, затем обновлял основной после того, как foreach был сделан, как вы можете видеть в моем коде выше, но это не исправило.

1 Ответ

2 голосов
/ 21 апреля 2019

У вас все еще есть один список. Следующая инструкция просто заставляет _btcTX указывать на тот же экземпляр списка, что и btcTX:

List<(string, SocketMessage, int)> _btcTX = btcTX;

Таким образом, основной список был изменен в Remove () и / или Add (). Один из способов удалить / добавить элементы - выполнить обычный цикл for с индексом (от последнего к первому), а затем вы сможете без проблем удалять / добавлять элементы. Другой способ состоял бы в том, чтобы сохранить цикл foreach, но сохранить индексы, которые нужно удалить, и элементы, которые нужно добавить, внутри цикла, а затем выполнить фактическое добавление / удаление после цикла (удаление должно выполняться с последнего индекса до первого). .

...