我有需要转换为数据表的对象列表。
集合长度存在 20K 或更多。
当我尝试使用Parallel.for
then 迭代集合时,它只是挂断并且花费了太长时间。
任何人都可以建议将对象列表最佳转换为数据表的最佳方法吗?
我有需要转换为数据表的对象列表。
集合长度存在 20K 或更多。
当我尝试使用Parallel.for
then 迭代集合时,它只是挂断并且花费了太长时间。
任何人都可以建议将对象列表最佳转换为数据表的最佳方法吗?
如果您已经在内存中拥有该对象,并且必须将它们转换为 DataTable,那么您就大错特错了。DataTable 不是线程安全的
而且您的内存使用量增加了一倍。
我唯一的建议是,也许您可以将现有集合包装在从 DataTable 继承的对象中并覆盖或隐藏方法,以便它们引用您的基础列表。
但是,我认为这不太可能是解决您的问题的“好”或简单的解决方案。最好的方法是消除对 DataTable 的需要
虽然DataTable 操作(包括 .NewRow() )不是线程安全的,但您的工作仍然可以 使用并行循环中的线程局部变量并行化:
List<string> source = Enumerable.Range(0, 20000).Select(i => i.ToString()).ToList();
DataTable endResult = CreateEmptyTable();
object lck = new object();
Parallel.For(
0, source.Count,
() => CreateEmptyTable(), // method to initialize the thread-local table
(i, state, threadLocalTable) => // method invoked by the loop on each iteration
{
DataRow dr = threadLocalTable.NewRow();
// running in parallel can only be beneficial
// if you do some CPU-heavy conversion in here
// rather than simple assignment as below
dr[0] = source[i];
threadLocalTable.Rows.Add(dr);
return threadLocalTable;
},
// Method to be executed when each partition has completed.
localTable =>
{
// lock to ensure that the result table
// is not screwed by merging from multiple threads simultaneously
lock (lck)
{
endResult.Merge(localTable);
}
}
);
在哪里
private static DataTable CreateEmptyTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("MyString");
return dt;
}
但是,只有在转换“您的对象实例”-> DataRow所节省的时间 大于在执行结束时加入结果所损失的时间(锁 + DataTable 合并)时,并行执行才会有益。仅当您的转换有点占用大量 CPU 时才有可能。在我的示例中,转换 (dr[0] = source[i]) 根本不会占用大量 CPU,因此更可取的是顺序执行。
PS。修改为按顺序运行的上述示例在我的 IntelCore-i7-3537U 上在 20 毫秒内完成。如果您的顺序执行时间很短,您可能根本不想打扰并行执行。