我完全脱离了我的元素,我承认我对这应该如何工作有点困惑。我有一个excel文档,我正在尝试以线程安全的方式解析它。
以下是我目前所拥有的:
public IEnumerable<DepartmentOfEnergyIndex> ParseJet(Workbook workbook)
{
var indecies = new ConcurrentQueue<DepartmentOfEnergyIndex>();
var worksheet = (Worksheet)workbook.Worksheets.Item["Data 6"];
Parallel.ForEach(worksheet.Rows, currentRow =>
{
indecies.Enqueue(
new DepartmentOfEnergyIndex
{
DOELastUpdated = currentRow[0],
DollarsPerGallon = currentRow[1],
RegionID = RegionEnum.USGC.ToInt(),
});
});
return indecies.ToArray();
}
我遇到的第一个问题(除了缺乏知识之外)是ForEach抛出了一个编译器错误:
Error 1 The type arguments for method
'System.Threading.Tasks.Parallel.ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Action<TSource>)'
cannot be inferred from the usage. Try specifying the type arguments explicitly.
基于这个例子。这本应该有效,但很好,工作表。Rows是Microsoft.Office.Interop.Excel.Range:
Parallel.ForEach<Range>(worksheet.Rows, currentRow =>
{
//same stuff
});
现在:
Error 1 The best overloaded method match for 'System.Threading.Tasks.Parallel.ForEach<Microsoft.Office.Interop.Excel.Range>(
System.Collections.Generic.IEnumerable<Microsoft.Office.Interop.Excel.Range>,
System.Action<Microsoft.Office.Interop.Excel.Range>)' has some invalid arguments
Okay Range继承自IEnumerable,但实际上它不是IEnumerable。
那么,我如何在线程安全庄园中迭代这里的行呢?
Rows
是实现IEnumerable
的Range
,但不是实现IEnumerable<T>
。我认为基础项也是Range
类型,所以您需要强制转换它们:
Parallel.ForEach(worksheet.Rows.Cast<Range>(), currentRow => {
// do something
});
这应该能解决编译器错误,但不一定能解决任何线程问题。
此外,我不知道首先迭代每一行是否是个好主意。99.999%的时间里,大多数可用的工作表空间都没有被使用,但这会迭代整个工作表,根据Excel的版本,可能会超过一百万行。