c# - Parallel.forEach(DataTable.AsEnumerable() 线程安全吗

标签 c# .net task-parallel-library

如下使用时

Parallel.ForEach(DataTable.AsEnumerable(), dr => {

    string str = dr["field1"].ToString();
     //.... other stuff
    dr["f1"] = o.A;
    dr["f2"] = o.B;
    dr["f3"] = o.C;

});

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

我会假设不是,但是有一种关于假设的说法....

最佳答案

documentation DataRow 类明确指出

This type is safe for multithreaded read operations. You must synchronize any write operations.

没有比这更具体的了。

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

更好的解决方案是在单独的结构(例如 one of the concurrent collections)中返回并行处理的任何结果(“其他东西”),并在循环完成时应用来自单个线程的更改。

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

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

关于c# - Parallel.forEach(DataTable.AsEnumerable() 线程安全吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9297249/

相关文章:

c# - 同时运行任务.NET 4.5

c# - 为什么不在 ContinueWith 中执行任务?

c# - 为什么 SQL 查询不运行?

c# - 使用 MSTest 测试异步 WCF 服务

c# - 重启后台 worker

c# - EntityType 'Movie_Category_Map' 没有定义键。定义此 EntityType 的键

c# - 使用 Task.Factory.StartNew() 后是否需要 Wait()?

c# - Workflow Foundation 4 中的依赖注入(inject)/IoC

c# - 如何 - 从进程列表中取消列出我的程序..?

c# - TextReader.ReadToEnd 与 Stream.CopyTo