epplus by use" parallel.for"导致未触发的异常

时间:2018-01-12 06:45:19

标签: c# excel multithreading

我使用epplus 4.1.0.0创建excel文件。以下是我的代码的一部分。 如果我使用for循环来运行它。没关系。当我使用Parallel.For运行时,它会导致像null引用异常这样的异常异常,或者说如果未设置模式类型则无法设置颜色。但有时代码不会引发任何异常。并且输出excel文件没问题。

Parallel.For(0, dt.Rows.Count, i =>
{
   worksheet.Cells[StartRow + i, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
   worksheet.Cells[StartRow + i, 1].Formula = "O" + (StartRow + i).ToString() + "&\"^\" &V" + (StartRow + i).ToString();
   worksheet.Cells[StartRow + i, 1].Style.Fill.BackgroundColor.SetColor(Color.Orange);
   worksheet.Cells[StartRow + i, 2].Style.Fill.PatternType = ExcelFillStyle.Solid;
   worksheet.Cells[StartRow + i, 2].Formula = "IF(ISERR(W" + (StartRow + i).ToString() + "*(60/AH" + (StartRow + i).ToString() + ")),\"\",W" + (StartRow + i).ToString() + "*(60/AH" + (StartRow + i).ToString() + "))";
   worksheet.Cells[StartRow + i, 2].Style.Fill.BackgroundColor.SetColor(Color.Orange);
   worksheet.Cells[StartRow + i, 3].Style.Fill.PatternType = ExcelFillStyle.Solid;
   worksheet.Cells[StartRow + i, 3].Formula = "G" + (StartRow + i).ToString() + "&\"^\" &V" + (StartRow + i).ToString();
   worksheet.Cells[StartRow + i, 3].Style.Fill.BackgroundColor.SetColor(Color.Orange);
   worksheet.Cells[StartRow + i, 4].Value = dt.Rows[i][8].ToString().Substring(0, dt.Rows[i][8].ToString().Length - 3);
   worksheet.Cells[StartRow + i, 5].Value = dt.Rows[i][9].ToString().Substring(0, dt.Rows[i][9].ToString().Length - 3);
   worksheet.Cells[StartRow + i, 6].Value = dt.Rows[i][8].ToString();
   worksheet.Cells[StartRow + i, 7].Value = dt.Rows[i][9].ToString();
   worksheet.Cells[StartRow + i, 8].Value = dt.Rows[i][4].ToString().Trim();
   });

1 个答案:

答案 0 :(得分:0)

似乎EPPlus Worksheet API不是线程安全的(至少一些单元操作)。可以并行处理不同的工作表,如here所述。

你可以检查EPPlus source code - 它包含一些锁,可能它应该是线程安全的(只有它的作者知道);如果你觉得你真的需要并行处理一个工作表,你可以在github上添加一个问题。

在大多数情况下,这有点意义,因为内部EPPlus使用锁来访问存储工作表数据的共享集合。如果您使用EPPlus API的代码运行缓慢,请尝试执行以下操作:

  • 不要将耗时的操作(数据准备,计算)与使用EPPlus API的代码混合起来
  • 重用ExcelRange对象

喜欢

var cellStyle = worksheet.Cells[StartRow + i, 1].Style;
cellStyle.Fill.BackgroundColor.SetColor(Color.Orange);
cellStyle.Fill.PatternType = ExcelFillStyle.Solid;