是Parallel.forEach(DataTable.AsEnumerable()线程安全的 [英] Is Parallel.forEach(DataTable.AsEnumerable() thread safe

查看:79
本文介绍了是Parallel.forEach(DataTable.AsEnumerable()线程安全的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按以下方式使用

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

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

});

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

where each thread works on its own datarow

我不会假设,但是关于假设...这句话.

I would assume not but but there's this saying about assumptions....

推荐答案

文档的DataRow类明确指出

The documentation of the DataRow class definitively states that

此类型对于多线程读取操作是安全的.你必须同步所有写操作.

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

没有比这更具体的东西了.

Can't get any more specific than that.

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

In any case, parallel writing to a Datatable is probably not going to scale well. Scalability suffers when you have multiple threads accessing shared state and a single datatable is quite obviously shared state. What's more, unless you work with NUMA hardware your CPU cores will contend for access to the same memory bus.

更好的解决方案是在单独的结构(例如

A much better solution is to return any results from the parallel processing (the "other stuff" ) in a separate structure (e.g. one of the concurrent collections) and apply the changes from a single thread when the loop finishes.

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

Another option is to use PLINQ to calculate the results and and iterate over them with a simple foreach to apply the changes back to the DataTable.

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

An even better solution would be to discard the original datatable entirely and return a new object that contains the fields you require. Unless your code requires the result to be a DataTable, you could simply return the results as an IEnumerable

这篇关于是Parallel.forEach(DataTable.AsEnumerable()线程安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆