当我致电datatable.Copy()
并且我不确定原因时,我收到以下异常。我应用了一个锁来避免这个问题,但它似乎没有解决它。异常不会一直发生,所以我知道它与线程有关。我误解了锁是如何工作的吗?
System.InvalidOperationException:修改了集合;枚举操作可能无法执行。 在System.Data.RBTree`1.RBTreeEnumerator.MoveNext() 在System.Data.DataTable.Copy()
代码:
DataTable dt;
lock (ClassName.datatable)
{
dt = ClassName.datatable.Copy();
}
ClassName
是一种类型,而不是一个对象(在我之前的一个问题中存在一些混淆)。
答案 0 :(得分:3)
根据评论判断,您误解了lock
的工作原理。这是一个协作方案,因此两个线程不能同时在同一个监视器上保持锁定。除非线程试图“输入”锁,使用lock
语句或Monitor.Enter
(和相关的调用),否则另一个线程持有锁的事实是无关紧要的。
这有点像没有锁的卫生间,而是一个“订婚”或“空置”的标志......没有人强迫要么自己改变标志,要么注意到它当前状态......但如果每个人同意同时执行这两项操作,则可以避免出现令人尴尬的情况。
我个人试图避免锁定任何其他代码可见的显示器,所以我可能会:
private readonly object tableLock = new objet();
private readonly DataTable table;
...
lock (tableLock)
{
...
}
你需要至少可能获得你使用表的无处不在的锁,当然如果你将它传递给其他可能存储对它的引用的方法,或者你给它的其他一些代码,你几乎无法控制它发生了什么。