您看到的错误告诉您,您正在尝试在枚举它时修改集合。 lock
关键字适用于多线程情况,它确保只有一个线程处于关键部分。它与“锁定”收集无关,因此您可以枚举它并修改它。
您通常看到的错误与代码中出现一样,如果你有一个线程枚举集,而其他线程添加或删除收集以下
foreach(var item in items)
{
//Inside this loop now you are enumerating collection
//This means you can't add or delete anything from items
items.Add(newItem); //This will produce the error you are seeing
}
也可能会出现此错误。所以如果你知道你有多线程的情况,那么你可以使用lock
,虽然它有点棘手,可能会影响你的并发性能,甚至会导致竞争状态。对于多线程情况,仅使用ToList
可能不够,因为在调用ToList
时需要确保只有一个线程可以访问集合。因此,您可能需要使用ToList
以及锁定,根据您的情况,它可能会更简单。要查看如何在枚举中进行线程安全修改的示例,请参阅此答案:Making a "modify-while-enumerating" collection thread-safe。
如果你知道你没有多个线程,那么ToList
可能是你唯一的选择,你根本不需要lock
。我还建议确定在枚举时是否确实需要修改集合。在许多情况下(但不是全部),您可以采取不同的设计,以避免它首先出现。
锁不起作用的情况下,列表在同一个线程上更改并且ToList不能使用列表线程安全 – Steven
这是在WCF服务中,我最好检查线程。我总是对线程和WCF感到困惑。 –
一般而言,Web服务可能意味着您的代码在理论上*在一个仲裁线程上被访问*。在我的Web服务中,我使用'ReadWriterLockSlim'来确保集合读取处于读取锁定状态,并且在更新时显然是写入锁定。 –