Parallel.For - 几乎让这个工作

时间:2012-07-09 19:18:50

标签: c# parallel-processing

我有大约3500个产品序列号的集合,我的软件用它来创建每周大约10次的报告。

我的代码从一个非常扁平的数据库(想想Excel电子表格)中检索,它从每个序列号的单个表中提取0到25+条记录。我将此数据传递给生成static实例的CustomClass方法,并将其存储在集合中,以便在例程结束时传回。

此报告通常需要大约20分钟才能运行。其中很多都受到发送到旧 SQL 2000 Server 的数据请求的限制,但编写静态类是为了减轻尽可能多的字符串操作和数据转换。

我想写一个Parallel.For来尝试让这次运行更快,但我无法弄清楚如何完成我的日常工作。

这是我现在的例程的简化版本:

private CustomClass[] Test1(string[] serialNumbers) {
  List<CustomClass> list = new List<CustomClass>();
  for (int i = 0; i < serialNumber.Length; i++) {
    DataTable table = new DataTable();
    using (SqlCommand cmd = new SqlCommand("sp_GetData", m_open_conn)) {
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add("@sn", SqlDbType.Char, 20).Value = serialNumber[i];
      table.Load(cmd.ExecuteReader());
    }
    list.Add(CustomClass.CreateSummary(table));
  }
  return list.ToArray();
}

任务是在Parallel.For循环中编写上面的代码。到目前为止我遇到的所有示例都过于简单,并且没有给我任何关于如何转换代码的见解。

这是我到目前为止所做的,但是第二个0值(我的Action / Func语句中的值)说Cannot implicitly convert type 'int' to 'jp2code.CustomClass' ...我真的不明白知道什么我需要做的就是完成这项工作。

private CustomClass[] Test1(string[] serialNumbers) {
  List<CustomClass> list = new List<CustomClass>();
  Parallel.For<CustomClass>(0, serialNumbers.Length, () => 0, (i, loop, list) => {
      DataTable table = new DataTable();
      using (SqlCommand cmd = new SqlCommand("sp_GetData", m_open_conn)) {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@sn", SqlDbType.Char, 20).Value = serialNumber[i];
        table.Load(cmd.ExecuteReader());
      }
    }, (x) => list.Add(CustomClass.CreateSummary(table))
  );
  return list.ToArray();
}

显然,我应该用一些东西(不是0)来初始化数组,但我不知道这里到底要做什么。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

由于您已经拥有一组固定的序列号,因此您实际上不需要Parallel.For

您可以使用PLINQ。

return serialNumbers.AsParallel().Select(number => { ...get table... }).ToArray();

我不会真的推荐ToArray()方法。

答案 1 :(得分:1)

我发现this blogParallel.For

的良好资源

要简单地替换for循环,您应该可以执行此操作:

private CustomClass[] Test1(string[] serialNumbers) {
  List<CustomClass> list = new List<CustomClass>();
  Parallel.For(0, serialNumber.Length, (i) => {
    DataTable table = new DataTable();
    using (SqlCommand cmd = new SqlCommand("sp_GetData", m_open_conn)) {
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add("@sn", SqlDbType.Char, 20).Value = serialNumber[i];
      table.Load(cmd.ExecuteReader());
    }
    list.Add(CustomClass.CreateSummary(table));
  });
  return list.ToArray();
}