1

我打电话时遇到以下异常,我datatable.Copy()不知道为什么。我应用了一个锁来避免这个问题,但它似乎没有解决它。异常不会始终如一地发生,所以我知道它与线程有关。我误解了锁的工作原理吗?

System.InvalidOperationException:集合已修改;枚举操作可能不会执行。在 System.Data.RBTree`1.RBTreeEnumerator.MoveNext() 在 System.Data.DataTable.Copy()

代码:

DataTable dt;

lock (ClassName.datatable)
{
    dt = ClassName.datatable.Copy();
}

ClassName是类型而不是对象(在我的上一个问题中有一些混淆)。

4

1 回答 1

3

从评论来看,你误解了它的lock工作原理。这是一个合作方案,两个线程不能同时在同一个监视器上持有锁。除非一个线程尝试使用lock语句或(和相关调用)“进入”锁,否则另一个线程持有Monitor.Enter锁的事实是无关紧要的。

这有点像一个没有锁的浴室,但有一个“订婚”或“空置”的标志......没有人被迫自己更改标志或注意到它的当前状态......但如果每个人都同意两者都做,你可以避免尴尬的情况。

就我个人而言,我尽量避免锁定任何其他代码可见的监视器,所以我可能会有:

private readonly object tableLock = new objet();
private readonly DataTable table;

...

lock (tableLock)
{
    ...
}

您至少需要在使用表的任何地方都可能获得锁- 当然,如果您将它传递给可能存储对它的引用的其他方法,或者您是由其他代码提供的,那么您实际上几乎没有控制权关于它发生了什么。

于 2012-06-20T16:47:52.030 回答