在 C# 开发中,很多时候会遇到 InvalidOperationException: Collection was modified
这样的异常。这个异常通常发生在遍历或修改集合时,导致集合的状态被并发地修改。
本篇博客将探讨这个异常的原因,并提供一些解决方法来避免或处理这个问题。
异常原因
异常 "Collection was modified" 引发的原因通常是由于在迭代集合的同时修改了集合的结构。当一个线程正在迭代集合的元素时,另一个线程同时修改了集合,这将导致并发的修改操作,进而引发该异常。
以下是一个示例代码:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
if (number % 2 == 0)
{
numbers.Remove(number); // 在迭代过程中移除元素
}
}
上述代码在迭代 numbers
列表时尝试移除偶数。然而,由于在迭代过程中对集合进行了修改操作,将会抛出 "Collection was modified" 异常。
解决方法
为避免 InvalidOperationException: Collection was modified
异常的发生,我们可以采取以下几种解决方法:
-
使用 for 循环代替 foreach 循环:使用 for 循环可以避免在迭代过程中移除或添加元素的问题。在循环中可以通过索引来访问集合的元素,从而避免并发修改。
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; for (int i = 0; i < numbers.Count; i++) { if (numbers[i] % 2 == 0) { numbers.Remove(numbers[i]); // 在迭代过程中移除元素 i--; // 由于移除了元素,需要减小索引以保持正确迭代 } }
-
使用线程同步机制:可以使用线程同步机制,如互斥锁(Mutex)或信号量(Semaphore),在操作集合之前进行同步。这样可以确保在一个线程正在修改集合时,其他线程无法同时进行修改。
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; Mutex mutex = new Mutex(); // 使用互斥锁同步操作 mutex.WaitOne(); // 在这里进行集合的修改操作 mutex.ReleaseMutex();
-
创建临时副本:在操作集合之前,可以创建一个临时副本来避免并发修改的问题。通过在副本上进行操作,可以避免在迭代期间改变原始集合的内容。
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; List<int> tempNumbers = new List<int>(numbers); // 创建副本 foreach (int number in tempNumbers) { if (number % 2 == 0) { numbers.Remove(number); } }
这些解决方法可以根据具体情况进行选择和调整,以解决 InvalidOperationException: Collection was modified
异常的问题。
希望本篇博客能够帮助您解决 C# 代码中的并发修改集合引发的异常问题。如有疑问或其他相关问题,请随时留言讨论。
本文来自极简博客,作者:健身生活志,转载请注明原文链接:解决C#代码中的InvalidOperationException: Collection was modified问题