【问题标题】:How to compare two DataTables and update the first DataTable using multiple threads?如何比较两个数据表并使用多个线程更新第一个数据表?
【发布时间】:2023-03-11 20:33:01
【问题描述】:

表1中有150,000条记录,我必须将表1中的每条记录与表2中的相应记录一一比较,如果找到匹配更新表1中的相同记录,如果找不到匹配需要更新Notes 表 1 中的列值未找到匹配记录。

为此,我分别从dtdt1 的两个表中获取记录。

下面是我做的代码

DataTable dt = getRecordsfromTable1();
DataTable dt1 = getRecordsfromTable2();
foreach(DataRow dr in dt.Rows)
{
     foreach(DataRow dr1 in dt1.Rows)
     {
          if(dr["Id"].ToString() == dr1["Id"].ToString())
          {
               //Calling update method in Data Access Layer to Update record in First table
               Update(dr["Id"].ToString());
          }
          else
         {
             //Id not found
         }
     }
}

但这工作非常缓慢,因为我正在逐一比较 150,000 条记录。如何在这里使用多线程概念来加快处理速度?

【问题讨论】:

  • 更好地使用针对这种事情特别优化的方法。您的代码效率极低且复杂度为 O(n^2) - 再多的多线程也不会显着加快速度。改为查看Enumerable.Join()(另外:您在ID 上对ToString() 的调用似乎是多余的,很可能)
  • 多线程对于 CPU 密集型计算很有用。这对 IO 不利。
  • 这个任务最好通过 MERGE SQL 语句来完成。
  • 比较 150,000 条记录不应该在 C# 中完成,因为它不是为这种类型的工作负载设计的。另一方面,数据库是明确的。为正确的工作使用正确的工具。
  • 150000 这不是很多记录。数据库已经可以比任何客户端快得多完成您要求的操作,因为它可以使用索引并且比任何客户端都拥有更快的 CPU、RAM 和磁盘。以数量级更快(1000、10K、100K)

标签: c# multithreading datatable console-application multitasking


【解决方案1】:

在这里尝试的第一件事是在Id 上建立索引,即

Dictionary<string, DataRow> lookup = new();
// index dt1
foreach(DataRow dr1 in dt1.Rows)
{
    var id = dr1["Id"].ToString();
    lookup.Add(id, dr1);
}
// now enumerate dt
foreach(DataRow dr in dt.Rows)
{
    var id = dr["Id"].ToString();
    if (lookup.TryGetValue(id, out var dr1))
    {
        //Calling update method in Data Access Layer to Update record in First table
        Update(id);
    }
}

注意:如果Update 实际上不需要dr1,您也可以将Dictionary&lt;string, DataRow&gt; 替换为已知ID 的HashSet&lt;string&gt;

至于并行化:这在很大程度上取决于 Update 所做的事情;并行化可能有用也可能没用。很高兴讨论更多,但是:需要看到它。如果它可以简单地并行化,那么可能简单地使用就足够了:

// now enumerate dt concurrently
Parallel.ForEach(dt.AsEnumerable(), dr =>
{
    var id = dr["Id"].ToString();
    if (lookup.TryGetValue(id, out var dr1))
    {
        //Calling update method in Data Access Layer to Update record in First table
        Update(id);
    }
});

但是,与数据库相关的代码必须是可并行化的。

【讨论】:

  • Parallel.ForEach 不工作给出错误。 System.AggregateException,连接未关闭,连接当前状态为正在连接
  • 我尝试了foreach,但完成过程花了4个小时
猜你喜欢
  • 2015-05-29
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多