我通过迭代收集并对其进行排序来填充数据集中的数据表:
foreach (var item in items)
{
DataRow newRow = dataTable.NewRow();
contractRow["column1"] = item.Value1;
contractRow["column2"] = item.Value2;
dataTable.Rows.Add(newRow);
}
dataTable.DefaultView.Sort = "column1 asc";
一切正常。
但是当我试图并行生成数据表时:
Parallel.ForEach(items, (item) =>
{
DataRow newRow = dataTable.NewRow();
contractRow["column1"] = item.Value1;
contractRow["column2"] = item.Value2;
lock (sync)
{
dataTable.Rows.Add(newRow);
}
});
dataTable.DefaultView.Sort = "column1 asc";
排序失败
ArgumentException:已添加具有相同键的项目。
知道为什么会这样吗?
答案 0 :(得分:0)
您需要锁定DataTable
被更改的整个部分,因为它们对于写入来说不是线程安全的,但这首先使Parallel.ForEach
失败的目的。
lock (sync)
{
DataRow newRow = dataTable.NewRow();
contractRow["column1"] = item.Value1;
contractRow["column2"] = item.Value2;
dataTable.Rows.Add(newRow);
}
有关DataTable
的线程安全的更多信息,请访问:
Thread safety for DataTable
答案 1 :(得分:0)
问题在于,与DataTable
一样,DataRow
对于读取操作只是线程安全的。 You have to sync for write operations.为ItemArray
分配值是一个写操作,并且不是线程安全的。您可能会获得两个具有相同的表主键值的行,从而导致错误。