我正在尝试使用反向dns映射来扩充一个IP地址在一列中的DataTable。我从其他地方获取此DataTable。然后我使用SQLBulkcopy
将此表导出到SQL Server我正在添加两列,一列用于dns名称,另一列用于顶级域名部分。我有很多IP并且做反向DNS需要一些时间我每个都使用并行。 奇怪的是,我在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("*");
});
答案 0 :(得分:4)
因为DataTable
对于多线程写操作不是线程安全的。
<强> MSDN says: 强>
此类型对于多线程读取操作是安全的。您必须同步任何写操作。
当您在Parallel.ForEach
执行此操作时,您正在同时编写包含多个主题的新列:
row["URL"] = URL;
row["Domain"] = GetTopLevelDomain(URL);
您需要同步对DataTable
的任何书写调用(使用锁或某种形式的监视器)