是Parallel.forEach(DataTable.AsEnumerable()线程安全的

本文关键字:线程 安全 DataTable Parallel forEach AsEnumerable | 更新日期: 2023-09-27 18:24:38

按以下使用时

Parallel.ForEach(DataTable.AsEnumerable(), dr => {
    string str = dr["field1"].ToString();
     //.... other stuff
    dr["f1"] = o.A;
    dr["f2"] = o.B;
    dr["f3"] = o.C;
});

其中每个线程在其自己的数据行上工作

我想不会,但有一句话是关于假设的。。。。

是Parallel.forEach(DataTable.AsEnumerable()线程安全的

DataRow类的文档明确指出

这种类型对于多线程读取操作是安全的。你必须同步任何写入操作。

再具体不过了。

在任何情况下,对数据表的并行写入都可能无法很好地扩展。当您有多个线程访问共享状态,而单个数据表显然是共享状态时,可伸缩性就会受到影响。更重要的是,除非使用NUMA硬件,否则CPU核心将争夺对同一内存总线的访问。

一个更好的解决方案是在一个单独的结构(例如一个并发集合)中返回并行处理的任何结果("其他东西"),并在循环结束时应用单个线程的更改。

另一种选择是使用PLINQ来计算结果,并使用简单的foreach对其进行迭代,以将更改应用回DataTable。

一个更好的解决方案是完全丢弃原始数据表,并返回一个包含所需字段的新对象。除非您的代码要求结果是DataTable,否则您可以简单地将结果作为IEnumerable 返回

DataTable对于写操作来说不是线程安全的。当您同时更改行时,您将更改DataTable的状态,因此这将导致问题。

如果这些列中有任何列被索引,那肯定是不安全的
如果不是,它可能是安全的,但我不这么认为。