我有以下DataTable
DataTable dt = new dataTable();
我从另一个方法填充了这个dataTable。在执行以下语句之前,它将具有50000行和40列。
行数和列数可能有所不同。因此我没有为dataTable定义特定的列集。
我想在末尾添加两列(guid和addeddate),并希望在这两列的所有50K行中添加相同的值。
我为此编写了简单的foreach循环。我有什么方法可以并行吗?
我尝试使用Parallel.Foreach但没有取得任何成功。
//by this time my dt will have 50000 rows and 40 columns
dt.Columns.Add(new DataColumn("guid", typeof(string)));
dt.Columns.Add(new DataColumn("addeddate", typeof(DateTime)));
string sessionIDValue = Convert.ToString(Guid.NewGuid());
DateTime todayDt = DateTime.Today;
foreach (DataRow row in dt.Rows)
{
row["guid"] = sessionIDValue;
row["addeddate"] = todayDt;
}
答案 0 :(得分:2)
您需要使用显式索引访问行,行索引将是完美的方法。
你应该能够创建一个等于你拥有的行数的数组(例如50000),每行的索引作为该数组的值(例如0..1..2..3 ..和等等)然后在索引数组上使用并行循环,从而将显式行索引传递给dt.Rows对象。
代码的要点是:
// Pseudo code
// Create array equal to size of the # of rows (int ArrayOfIndexes[])
// Fill that array with values representing row indexes starting at 0
Parallel.ForEach(ArrayOfIndexes, (index) =>
{
lock(dt)
{
dt.Rows[index]["guid"] = sessionIDValue;
dt.Rows[index]["addeddate"] = todayDt;
}
}
编辑:我确实发现,由于DataTable不是线程安全的,您必须在分配中包含锁,这显然会产生性能损失,但仍应该是比没有Parallel.ForEach的简单循环更快。
答案 1 :(得分:0)
升级@Shane Oborn的答案,没有额外的ArrayOfIndexes变量,并使用单独的锁定对象。
我会用:
var lockObj = new object();
Parallel.Foreach(dt.AsEnumerable(), row =>
{
lock(lockObj)
{
row["guid"] = sessionIDValue;
row["addeddate"] = todayDt;
}
});
您必须添加using语句:
using System.Data.DataSetExtensions;
using System.Linq;
using System.Xml;