0

我收集了大约 3500 个产品序列号,我的软件使用这些序列号每周创建大约 10 次报告。

我的代码从一个非常扁平的数据库(想想 Excel 电子表格)中检索,它从一个表中为每个序列号提取 0 到 25+ 条记录。我将此数据传递给static生成 my 实例的方法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();
}

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

有人可以帮忙吗?

4

2 回答 2

2

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

您可以使用 PLINQ。

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

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

于 2012-07-09T19:27:16.473 回答
1

我发现这个博客是一个很好的资源Parallel.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();
}
于 2012-07-09T19:31:18.743 回答