我在这段代码中遇到了这个异常,无法理解为什么
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
)后抛出该
stacktrace中的异常行是包含foreach (var tx in btcTX)
的那一行
我尝试使用2个不同的列表,然后在foreach
完成后更新主列表,正如您在上面的代码中看到的那样,但是没有解决。
答案 0 :(得分:2)
您仍然有一个列表。 以下语句仅使_btcTX指向与btcTX相同的列表实例:
List<(string, SocketMessage, int)> _btcTX = btcTX;
因此实际上实际上是在Remove()和/或Add()中修改了主列表。 删除/添加项目的一种方法是使用索引(从最后到第一个)执行常规的for循环,然后您就可以毫无问题地删除/添加项目。 另一种方法是保留foreach循环,但将要删除的索引和要添加的项目存储在循环内,然后在循环后执行实际的添加/删除操作(应从最后一个索引删除到第一个索引)