【问题标题】:C# datatable add method from multiple threads?来自多个线程的 C# 数据表添加方法?
【发布时间】:2012-09-21 12:59:50
【问题描述】:

我正在使用 .net 3.5 数据表并从多个线程向数据表添加行。当不使用锁时,我得到 datatablr 行数和最大索引之间的不匹配。当试图序列化表时,我得到一个异常there is no rows at poitions X。当然我可以锁定数据表,但我想知道是什么原因。我希望row.count() 方法基于行最大索引+1 返回,而不是具有非独立计数器。另外,我在哪里可以找到rows.Add (params) 方法的内部实现?即使在某些情况下添加在同一行上,每次添加似乎计数器都会增加。

编辑:感谢 cmets。我确实知道它不是线程安全的写入并且已经通过在同步根对象上使用锁定来解决它。我想看看 add 方法内部发生了什么,看看计数在哪里搞砸了。

【问题讨论】:

  • 来自 DataTable docs 的引用:这种类型对于多线程读取操作是安全的。您必须同步任何写入操作。 (msdn.microsoft.com/en-us/library/…)
  • 发布您的示例代码,以便我们尝试复制问题。
  • 您可以轻松重现它:DataTable dt = new DataTable(); for (int i = 0; i dt.Rows.Add(new object[] {})).Start(); } 现在检查计数值和行列表。他们不相等。
  • @AntonioBakula,如果我能对该评论 +1 一百万次,我愿意。编程中一个非常常见的错误是假设多线程只是完全封装而您不必担心。这几乎和人们想的一样大的错误,因为 .NET 中有“垃圾收集”,他们不必关心如何设置和限定对象引用。

标签: c# datatable


【解决方案1】:

原因很简单:DataTable 不是线程安全的。它没有声称 是线程安全的(反对竞争性写入),并且要求 是线程安全的。大多数代码不是线程安全的,除非有明确说明“我在以下情况下是线程安全的”,否则您应该假设它不是。 p>

最常见的是,在这种情况下,它意味着以下之一:

  • 索引更新丢失,即两者同时执行count++,此时它仅上升 1
  • 当数组被复制、增长、缩小或重新排列时,一个操作会导致疯狂的数据

修复很简单:如果任何线程正在更改表,它必须具有独占访问权限。所以同步。 lock 是最简单的选项,但还有更多奇特的选项,例如 ReaderWriterLockSlim。

那么下一步就是决定:我们真的想要使用DataTable吗?

【讨论】:

  • 所以ReaderWriterLockSlim 类使用基本的lock,但只是有更复杂的环境被封装在远离你的地方?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多