【问题标题】:indexoutofrangeexception in Datatable with Parallel.Foreach带有 Parallel.Foreach 的数据表中的 indexoutofrange 异常
【发布时间】:2014-06-03 02:01:34
【问题描述】:

我正在尝试通过反向 dns 映射来扩充一个在一列中有 IP 地址的 DataTable。我从其他地方得到这个数据表。然后我使用 SQLBulkcopy 将此表导出到 SQL Server

我要添加两列,一列用于 dns 名称,另一列仅用于顶级域部分。因为我有很多 IP 并且做反向 DNS 需要一些时间,所以我为每个使用 Parallel。 奇怪的是,我在并行循环的 NestedException 中得到了奇怪的不可预测的 IndexOutOfRangeExceptions(或者当我在数据表中调用 clear 时有时在并行循环之外)。为什么?

这就是我正在做的事情

        //mapping specifies a mapping within the DataTable and the Database

        SqlBulkCopy copy = new SqlBulkCopy(cn);
        foreach (KeyValuePair<int, int> pair in mapping)
        {                                                                       
            copy.ColumnMappings.Add(pair.Key, pair.Value);
        }


        dt.Columns.Add("URL");
        dt.Columns.Add("Domain");
        solver.AddDNSInfo(dt, 1); //second row has the IP
        copy.WriteToServer(dt);
        dt.Clear();     //exceptions are thrown here   




    //ipIndex is the index within the datatable where the IP of interest is. 
    //In my scenario ipIndex=1
    public void AddDNSInfo(DataTable table, int ipIndex)
    {
        Parallel.ForEach(table.AsEnumerable(), row =>
        {
                string URL = GetDNSName((string)row[ipIndex]);
                row["URL"] = URL; //exceptions are thrown here
                row["Domain"] = GetTopLevelDomain(URL);
                Console.Write("*");
        });

【问题讨论】:

  • 您的数据表中似乎没有添加任何行
  • 我从程序的另一部分获取 dt,该部分从文本文件加载数据。我会添加它

标签: c# datatable parallel-processing sqlbulkcopy parallel.foreach


【解决方案1】:

因为DataTable 对于多线程写操作来说不是线程安全的。

MSDN says:

这种类型对于多线程读取操作是安全的。您必须同步所有写入操作。

当您在 Parallel.ForEach 中同时编写具有多个线程的新列时:

  row["URL"] = URL;
  row["Domain"] = GetTopLevelDomain(URL);

您需要将任何写入调用同步到您的DataTable(使用锁或某种形式的监视器)

【讨论】:

  • 是的。这完全解决了它。谢谢!
猜你喜欢
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
相关资源
最近更新 更多