Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#多线程的datatable add方法?_C#_Datatable - Fatal编程技术网

C#多线程的datatable add方法?

C#多线程的datatable add方法?,c#,datatable,C#,Datatable,我正在使用.NET3.5DataTable并从多个线程向datatable添加行。如果不使用lock,则DataTabler行数与最大索引之间不匹配。尝试序列化表时,我得到一个异常,在点X处没有行。当然我可以锁定数据表,但我想知道原因是什么。我希望row.count()方法返回的基是行maxmimum index+1,而不是非独立计数器。另外,在哪里可以找到行.Add(params)方法的内部实现?似乎每次添加时计数器都会上升,即使在soem情况下,添加在同一行上 编辑:谢谢您的评论。我知道它不

我正在使用.NET3.5DataTable并从多个线程向datatable添加行。如果不使用lock,则DataTabler行数与最大索引之间不匹配。尝试序列化表时,我得到一个异常
,在点X处没有行。当然我可以锁定数据表,但我想知道原因是什么。我希望
row.count()
方法返回的基是行maxmimum index+1,而不是非独立计数器。另外,在哪里可以找到
行.Add
(params)方法的内部实现?似乎每次添加时计数器都会上升,即使在soem情况下,添加在同一行上


编辑:谢谢您的评论。我知道它不是线程安全的写入,并且已经通过在syncroot对象上使用锁来解决它。我想看看add方法内部发生了什么,看看计数哪里出错。

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

在这种情况下,最常见的情况是指:

  • 索引更新正在丢失,即两个都在同时进行
    count++
    ,但只增加了1
  • 在复制、增长、缩小或重新排列阵列时,操作会导致数据丢失
修复方法很简单:如果任何线程正在更改表,它必须具有独占访问权限。所以同步
lock
是最简单的选项,但也存在像ReaderWriterLockSlim
这样的更奇特的选项


然后下一步是决定:我们真的想使用
DataTable

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

在这种情况下,最常见的情况是指:

  • 索引更新正在丢失,即两个都在同时进行
    count++
    ,但只增加了1
  • 在复制、增长、缩小或重新排列阵列时,操作会导致数据丢失
修复方法很简单:如果任何线程正在更改表,它必须具有独占访问权限。所以同步
lock
是最简单的选项,但也存在像ReaderWriterLockSlim这样的更奇特的选项


然后下一步将是决定:我们真的想使用
DataTable

引用DataTable文档:这种类型对于多线程读取操作是安全的。必须同步任何写入操作。()发布您的示例代码,以便我们可以尝试并复制问题。您可以轻松地复制它:DataTable dt=new DataTable();对于(inti=0;i<500;i++){new Thread(()=>dt.Rows.Add(new object[]{})).Start();}现在检查计数值和行列表。他们并不平等。@AntonioBakula,如果我能+1这个评论一百万次,我会的。编程中一个非常常见的错误是假设多线程只是完全封装的,您不必担心它。这几乎和人们所想的一样大,因为在.NET中存在“垃圾收集”,他们不必关心如何设置和确定对象引用的范围。引用数据表文档:这种类型对于多线程读取操作是安全的。必须同步任何写入操作。()发布您的示例代码,以便我们可以尝试并复制问题。您可以轻松地复制它:DataTable dt=new DataTable();对于(inti=0;i<500;i++){new Thread(()=>dt.Rows.Add(new object[]{})).Start();}现在检查计数值和行列表。他们并不平等。@AntonioBakula,如果我能+1这个评论一百万次,我会的。编程中一个非常常见的错误是假设多线程只是完全封装的,您不必担心它。这几乎和人们认为的一样大的错误,因为有“垃圾收集”在.NET中,他们不必关心如何设置和确定对象引用的范围。因此,
ReaderWriterLockSlim
类使用基本的
lock
,但只是有一个更复杂的环境被封装在远离您的地方?因此
ReaderWriterLockSlim
类使用基本的
lock
,但是有更复杂的环境,是封装远离你?