异常 "集合已被修改",实际上却没有被修改

3
我使用这段代码时遇到了异常,但不明白原因。
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
你还有一个列表。 以下语句只是让_btcTX指向与btcTX相同的列表实例:

最初的回答:

你仍然拥有一个列表。

以下语句只是让_btcTX指向与btcTX相同的列表实例:

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

实际上,主列表是在Remove()和/或Add()中进行修改的。 一种删除/添加项目的方法是使用常规的for循环并带有索引(从后往前),然后您就可以轻松地删除/添加项目。 另一种方法是保留foreach循环,但在循环内部存储要删除的索引和要添加的项目,然后在循环后执行实际的添加/删除操作(删除应该从最后一个索引开始)。


哦,所以问题在于它指向同一个列表,我实际上认为它会创建一个新的列表,其中包含其他列表中的相同项目。非常感谢! - Stéphanie Autire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接