简体   繁体   English

例外情况“收集已被修改”,但尚未修改

[英]Exception “Collection has been modified”, when it hasn't been

I'm getting this exception with this code and can't understand why 我使用此代码得到此异常,无法理解原因

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);
            }
        }
    });
}

It's thrown after processing the first list element ( foreach ) 在处理第一个列表元素( foreach )之后抛出它

The exception line from the stacktrace is the one containing foreach (var tx in btcTX) stacktrace中的异常行是包含foreach (var tx in btcTX)

I tried using 2 different lists then updating the main one once the foreach is done, as you can see in my code above, but it didn't fix. 我尝试使用2个不同的列表,然后在foreach完成后更新主要列表,正如您在上面的代码中看到的那样,但它没有修复。

You still have one list. 你还有一个清单。 The following statement just causes _btcTX to point to the same list instance as btcTX: 以下语句只是使_btcTX指向与btcTX相同的列表实例:

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

So actually the main list was modified in the Remove() and/or Add(). 实际上,主要列表在Remove()和/或Add()中被修改。 One way to remove/add the items is to perform a regular for loop with an index (from last to first), and then you will be able to remove/add items with no problem. 删除/添加项目的一种方法是使用索引(从最后到第一个)执行常规for循环,然后您将能够毫无问题地删除/添加项目。 Another way would be to keep the foreach loop, but store the indices to be removed and the items to be added inside the loop and then perform the actual adding/removal after the loop (removing should be done from the last index to the first). 另一种方法是保持foreach循环,但是存储要删除的索引和要在循环内添加的项,然后在循环之后执行实际的添加/删除(从最后一个索引到第一个索引应该删除) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM