List <T>与一个Writer,No Enumerators的线程安全性

Chu*_*huu 5 c# list thread-safety concurrent-programming

在查看一些与此问题无关的错误的数据库代码时,我注意到在某些地方List<T>使用不当.特别:

  1. 有许多线程同时访问List作为读者,但使用索引list的,而不是enumerators.
  2. 有一位作家list.
  3. 没有同步,读者和编写者同时访问list,但由于代码结构,在执行返回的方法之前永远不会访问最后一个元素Add().
  4. 没有任何元素被删除list.

通过C#文档,这不应该是线程安全的.但它从未失败过.我想知道,因为具体实施的,List(我在内部假定它是一个数组重新allocs当它运行的空间),它的1-作家0枚举正阅读器插件唯一的方案偶然线程安全的,或者是否有一些不太可能的情况,这可能会在当前的.NET4实现中爆炸

编辑:重要细节我遗漏了阅读一些回复.读者将List其内容视为只读.

Jal*_*aid 1

因为它从未失败过或者您的应用程序没有崩溃,但这并不意味着这种情况是线程安全的。例如,假设编写器线程确实更新了列表中的一个字段,可以说这是一个long字段,同时读取器线程读取该字段。返回的值可能是旧字段和新字段两个字段的按位组合!可能会发生这种情况,因为读取器线程开始从内存中读取值,但在完成读取之前,写入器线程刚刚更新了它。

编辑:当然,如果我们假设读取器线程只会读取所有数据而不更新任何内容,我确信它们不会更改它们自己的数组的值,但是它们可以更改数组中的属性或字段他们阅读的价值。例如:

for (int index =0 ; index < list.Count; index++)
{
    MyClass myClass = list[index];//ok we are just reading the value from list
    myClass.SomeInteger++;//boom the same variable will be updated from another threads...
}
Run Code Online (Sandbox Code Playgroud)

这个例子没有讨论列表本身的线程安全,而是讨论列表公开的共享变量。

结论是,您必须使用同步机制lock,例如在与列表交互之前,即使它只有一个写入器并且没有删除任何项目,这将帮助您防止出现可有可无的小错误和故障情况。