- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在转换现有应用程序以利用多个处理器。我有一些嵌套循环,并且我已将最内层循环转换为 Parallel.Foreach 循环。在原始应用程序中,在最内层循环中,代码将调用 DataTable.NewRow()
要实例化适当布局的新 DataRow,填充列并将填充的 DataRow 添加到带有 DataTable.Add()
的 DataTable 中.但由于 DataTable 仅对读取操作是线程安全的,因此我将处理过程转换为将填充的 DataRow 对象添加到 ConcurrentBag<DataRow>
中。目的。然后,一旦 Parallel.Foreach 循环完成,我将迭代 ConcurrentBag 并将 DataRow 对象添加到 DataTable 中。看起来像这样……
DataTable MyDataTable = new DataTable()
// Add columns to the data table
For(int OuterLoop = 1; OuterLoop < MaxValue; OuterLoop++)
{
//Do Stuff...
ConcurrentBag<DataRow> CB = new ConcurrentBag<DataRow>();
Parallel.Foreach(MyCollectionToEnumerate, x =>
{
//Do Stuff
DataRow dr = MyDataTable.NewRow();
// Populate dr...
CB.Add(dr);
{);
ForEach(DataRow d in CB)
MyDataTable.Add(d);
}
所以当它运行时,我看到“索引超出了数组的范围。”调用 MyDataTable.NewRow()
时出现异常.但是 NewRow() 不是线程安全的读取操作吗?当然,它实例化了一个新的 DataRow 对象,这不是读取。但它不需要修改 DataTable 对象,不是吗?
这可能有点帮助...当我查看异常时,我的调用堆栈中的前两项是...
at System.Data.DataTable.NewRow(Int32 record)
at System.Data.DataTable.NewRow()
at ...
我看到了 NewRow()
调用必须是私有(private)的 NewRow(int32)
方法。所以也许这就是问题所在。但我不确定如何解决它。如果必须的话,我可以开始创建,而不是从我的 Parallel.Foreach 循环中实例化 DataRow 对象,只需实例化一个看起来很像我的 DataTable 的自定义对象,一旦循环退出,实例化实际的 DataRows 并将它们添加到数据表。但这不够优雅,并且会实例化“不必要的”对象。我的目标是提高性能,所以这似乎适得其反。
感谢您的帮助。
最佳答案
不,NewRow
不是“读”操作,也不是线程安全的。
除了使用 NewRow
并填充行之外,您还可以将您的值放在数组或 object
列表中。然后,当您收集完所有数据后,您可以将其全部添加到 DataTable
。
var newRow = table.NewRow();
newRow.ItemArray = values; // array of values
table.Rows.Add(newRow);
这样,当您将数据添加到 DataTable
时,您可以并行创建数据而不会遇到问题。
查看 source code对于 DataTable
:
它包含各种字段:
private readonly DataRowBuilder rowBuilder;
internal readonly RecordManager recordManager;
NewRow()
调用 NewRow(-1)
,NewRow(int)
修改这些字段的状态:
internal DataRow NewRow(int record) {
if (-1 == record) {
record = NewRecord(-1);
}
rowBuilder._record = record; // here
DataRow row = NewRowFromBuilder( rowBuilder );
recordManager[record] = row; // here
if (dataSet != null)
DataSet.OnDataRowCreated( row );
return row;
}
...还有很多我没有跟进。但显而易见的是,NewRow()
不仅仅返回一个新行 - 它修改整个地方的 DataTable
实例的状态。
文档从来没有说它是线程安全的,但我猜是因为你仍然需要将行添加到表中,所以 NewRow
没有修改 DataTable
。但我错了,它绝对不是线程安全的。
另一个标志在 documentation for NewRow
中
After creating a DataRow, you can add it to the DataRowCollection, through the DataTable object's Rows property. When you use NewRow to create new rows, the rows must be added to or deleted from the data table before you call Clear.
它没有说明如果调用 Clear()
而不添加或删除使用 NewRow()
创建的行会发生什么。异常(exception)?我会死吗?所以我试过了。我还在这里,但是调用 Clear()
将每行中的所有值替换为 DBNull.Value
,进一步强调这些行在它们出现之前不会“脱离实体”被添加到 DataTable
。它们是其状态的一部分。
关于c# - Parallel.ForEach 和 DataTable - DataTable.NewRow() 不是线程安全的 "read"操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56224441/
这是一个假设性问题。如果我有来自 3 个单独的 sql db 查询的 3 个数组,这些查询都与另一个数组相关。例如…… //db schools id | school_name classes id
在我的应用程序中,我使用 scrape(string url) 方法从网页中抓取链接。可以说它每次都返回我 10 个 url。 我想从每个抓取的 url 中抓取 10 个链接。 长话短说: (第 1
我的java7代码: final Map result = new HashMap<>(); final Set> classes = getClasses(co.glue()); for (fina
是否可以在 SwiftUI 中设置变量,例如在这样的 ForEach 中: struct ContentView: View { var test: Int var body: som
在 D、int、uint 中使用 foreach 时,循环索引的首选类型是什么?或者只是通过省略类型自动实现? 最佳答案 一般来说,索引应该是size_t。与长度相同。如果您尝试使用 int 或 ui
根据 http://dlang.org/statement.html 的“Foreach 限制”部分以下代码 int[] a; int[] b; foreach (int i; a) { a
在什么情况下我们应该在 JDK 8 中使用旧的 foreach 循环遍历新的 collection.forEach() 还是最好的做法是转换 every foreach 循环?是否存在任何重要的性能差
获得类似东西的惯用方法是什么? ((fn [coll] (function-body)) [:a :b :c :d]) -> [[:a :b][:a :c][:a :d][:b :c][:b :d][
我正在创建一个基于 who is it? 的 Java 应用程序。现在我正在制作一种方法,在回答问题时我需要其他卡片。 我有两个列表: 列表是一个 ImageView 列表,其中我有卡片必须代表的 2
我希望有人能在我发疯之前帮助我。 我有 3 张 table : Table A SELECT companypk, companyname, logo, msscope FROM global_com
我正在尝试将多个字符串添加到 C# 中的 MailAddress。 如果我使用ForEach,我的代码会是这样 foreach (var item in GetPeopleList()
我没有太多的 C# 经验,所以如果有人能指出正确的方向,我将不胜感激。我有一个引用对象变量的 foreach 循环。我希望在主循环中创建另一个 foreach 循环,将当前变量与对象数组中的其余变量进
下面的代码每 60 秒删除文件夹“Images”中的文件,它可以工作,但是当文件夹为空时它会显示:警告:为 foreach() 提供的参数无效如果没有文件,如何解决这个问题,说“文件夹为空而不是那个警
我需要在两种不同的模式下运行,因此“if”(第二个稍后构建一个大的 csv) 下面对于单个实例运行正常,但在第二个 (*) 的加载时间上失败,因为在前 7k 行中的每一行上运行。 我想避免可怕的事情
我们可以使用以下两种方法实现类数组对象的迭代: let arrayLike = document.getElementsByClassName('dummy'); [].forEach.call(ar
我有这个代码 ... 它说: Attribute value invalid for tag forEach according to TLD 最佳答案 forEach标签不支持 valu
我在 SwiftUI 中有一个像这样的 ForEach: ForEach(entries) { (e: MyType) in NavigationLinkItem(entry: e) } 现在我
我无法在一个 Foreach 或 Foreach-Object 循环中使用多个命令 我的情况是—— 我有很多文本文件,大约 100 个。 所以他们被阅读 Get-ChildItem $FilePath
我必须从 json 文件(实际上是 2 个 json 文件)执行 ForEach,因此我执行 2 forEach,代码是 table { font-family: arial, sans-
我对编程很陌生,当我执行 forEach 函数时,我的应用程序返回错误。我的controller.js中有以下代码 $scope.ajaxRequest = A.Game.get({action: '
我是一名优秀的程序员,十分优秀!