.NET CLR-对象引用同步

.NET CLR-对象引用同步,.net,multithreading,thread-safety,clr,.net,Multithreading,Thread Safety,Clr,在多线程.NET应用程序中 假设第一个线程正在写入列表 第二个线程正在清除中的所有项目。 第三个线程正在从列表中读取 如果第二个和第三个线程在CLR级别上“实际上”同时访问同一个列表对象,会发生什么情况。我不是指.NET同步对象和锁机制 我的意思是,当CLR从引用(通过第三个线程)访问列表项时,如果引用所指向的列表发生更改(通过第二个线程),会发生什么情况?它会崩溃InvalidOperationException。糟糕的东西 此类型的公共静态(在Visual Basic中共享)成员是线程安全的

在多线程.NET应用程序中

假设第一个线程正在写入列表 第二个线程正在清除中的所有项目。 第三个线程正在从列表中读取

如果第二个和第三个线程在CLR级别上“实际上”同时访问同一个列表对象,会发生什么情况。我不是指.NET同步对象和锁机制


我的意思是,当CLR从引用(通过第三个线程)访问列表项时,如果引用所指向的列表发生更改(通过第二个线程),会发生什么情况?

它会崩溃<由于枚举已更改,将引发代码>InvalidOperationException。

糟糕的东西

此类型的公共静态(在Visual Basic中共享)成员是线程安全的任何实例成员都不能保证线程安全。

A
列表
可以同时支持多个读卡器,只要不修改集合即可。通过集合枚举本质上不是线程安全的过程。在枚举与一个或多个写访问争用的罕见情况下,确保线程安全的唯一方法是在整个枚举期间锁定集合。要允许多个线程访问集合进行读写,您必须实现自己的同步。

如果您倾向于更新列表并在多线程代码中读取它,那么可能会发生很多失败,例如,假设我们有以下场景:

//c#
List<object> myList...

//at reading thread
if (myList.Count > 0)
{
    object item = myList[0];//get the item at the first index of the collection.
}

//at writing thread
myList.Clear();
/c#
列出我的列表。。。
//在阅读线程时
如果(myList.Count>0)
{
object item=myList[0];//获取集合第一个索引处的项。
}
//在写线程时
myList.Clear();
写入线程在读线程从列表读取的同时更新列表,因此假设执行如下:
读卡器线程检查集合中是否有项目,并发现其中有一些ITM“
.Count>0
为true”,因此它继续进行,但在到达下一行之前,线程上下文切换通过切换到编写器线程来暂停读卡器线程,因此它执行its code
myList.Clear()
此时线程上下文切换回读线程继续执行,因此它尝试获取
myList[0]
,但写入线程此时集合为空,因此它将失败,出现异常
indexoutfrange

另一种情况是,如果进行迭代的读线程使用
foreach
抛出集合,而写线程只是更改集合“添加/删除”某些项,它将再次抛出异常,因为循环时集合已更改


因此,在与列表交互时,您必须使用一些同步机制,例如C#中的
lock
,或者使用
Monitor
class。。但是,如果您使用的是
4.0
,则可以切换到使用
ConcurrentCollection
而不是普通列表,它们是线程安全的集合。

没有使用枚举。考虑简单地访问列表的第一项