Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# 是Parallel.forEach(DataTable.AsEnumerable()线程安全的_C#_.net_Task Parallel Library - Fatal编程技术网

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

C# 是Parallel.forEach(DataTable.AsEnumerable()线程安全的,c#,.net,task-parallel-library,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; }); 其中每个线程在其自己的数据行上工作 我想不会,但关于假设有这样一种说法……如果这些列中有任何列被索引,它肯

当按如下方式使用时

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

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

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


我想不会,但关于假设有这样一种说法……

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

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

DataRow类的

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

没有比这更具体的了

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

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

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


更好的解决方案是完全放弃原始数据表,并返回一个包含所需字段的新对象。除非代码要求结果为数据表,否则只需将结果作为IEnumerable返回即可。datatable是一个极其复杂的beast可能是愚蠢的回答。“假设把
u
mptions
弄得一团糟”?Psst.。俗话说的是“假设”而不是“假设”;@SLaks,DataTable很复杂,但也很灵活-其复杂性的来源:)只是想在这个特定的情况下获得一些颜色而已@库马尔:是的。但是,它不太可能是线程安全的。一般来说,是的,但是每个线程都在不同的行上工作,因此该行本身没有并发操作,因此关于这个特定的scenario@Kumar即使每个线程在不同的行上工作,该行包含在DataTable中,当您对该行执行写操作时,DataTable的状态会受到影响。@Kumar:不具体。如果你感兴趣的话,可以看看这个网站。祝你好运这非常复杂。你说的“如果……列被索引”是什么意思?访问模式如图所示above@Kumar:
DataTable
有索引,就像SQLServer一样。修改索引列肯定是不安全的,即使跨行修改也是如此。列定义是静态的,因此在这方面不必担心,虽然在使用.net 2构建的应用程序中就是这样,但猜测在.net中性能会更好4@Kumar:两方面都错了。ADO.Net数据集在.NET4中根本没有改变。???这里怎么了?这是猜测!如果你随便看看,你会发现即使公共界面没有改变,内部也会发生变化,干杯!如果我理解您的答案:例如,如果我需要修改包含200行的数据表中的X列,我可以从X列中提取所有200行的值,并将其存储在并发集合中,然后对该并发集合执行Parallel.for()来更改值,然后在单个线程上循环,从并发集合中的值更新原始DataTable的列X?否,相反。从多个线程读取值没有问题,因此不需要提取它们。假设确实需要并行处理200个值,您应该在并发集合中收集处理结果,然后从单个线程将它们应用到表中。200只是我想到的一个随机数,但更像是数千个。在我的情况下,数据库中有一个表,该表中的1列被加密。我将db中这个表中的所有行加载到一个DataTable中,然后我需要遍历所有行并解密该列——这是一个相当简单的问题。我想我理解你的评论,因为我可以同时读取值并解密它们,但要更新原始行和列,我必须在单个线程中完成。