- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
这是一个非常奇怪的情况,首先是代码......
编码
private List<DispatchInvoiceCTNDataModel> WorksheetToDataTableForInvoiceCTN(ExcelWorksheet excelWorksheet, int month, int year)
{
int totalRows = excelWorksheet.Dimension.End.Row;
int totalCols = excelWorksheet.Dimension.End.Column;
DataTable dt = new DataTable(excelWorksheet.Name);
// for (int i = 1; i <= totalRows; i++)
Parallel.For(1, totalRows + 1, (i) =>
{
DataRow dr = null;
if (i > 1)
{
dr = dt.Rows.Add();
}
for (int j = 1; j <= totalCols; j++)
{
if (i == 1)
{
var colName = excelWorksheet.Cells[i, j].Value.ToString().Replace(" ", String.Empty);
lock (lockObject)
{
if (!dt.Columns.Contains(colName))
dt.Columns.Add(colName);
}
}
else
{
dr[j - 1] = excelWorksheet.Cells[i, j].Value != null ? excelWorksheet.Cells[i, j].Value.ToString() : null;
}
}
});
var excelDataModel = dt.ToList<DispatchInvoiceCTNDataModel>();
// now we have mapped everything expect for the IDs
excelDataModel = MapInvoiceCTNIDs(excelDataModel, month, year, excelWorksheet);
return excelDataModel;
}
IndexOutOfRangeException
在线上
dr[j - 1] = excelWorksheet.Cells[i, j].Value != null ? excelWorksheet.Cells[i, j].Value.ToString() : null;
i
的一些随机值和
j
.当我跳过代码(
F10
)时,由于它在 ParallelLoop 中运行,因此其他一些线程被踢出并抛出其他异常,该其他异常类似于(我无法重现它,它只出现过一次,但是我认为这也与这个线程问题有关)
Column 31 not found in excelWorksheet
.我不明白这些异常怎么会发生?
IndexOutOfRangeException
甚至不应该发生,因为唯一的代码/共享变量
dt
我已经锁定访问它,其余的都是本地或参数,所以不应该有任何与线程相关的问题。另外,如果我检查
i
的值或
j
在调试窗口中,甚至评估整个表达式
dr[j - 1] = excelWorksheet.Cells[i, j].Value != null ? excelWorksheet.Cells[i, j].Value.ToString() : null;
或者它的一部分在调试窗口中,然后它工作得很好,没有任何类型的错误或什么都没有。
using (var xlPackage = new ExcelPackage(viewModel.postedFile.InputStream))
{
ExcelWorksheets worksheets = xlPackage.Workbook.Worksheets;
// other stuff
var entities = this.WorksheetToDataTableForInvoiceCTN(worksheets[1], viewModel.Month, viewModel.Year);
// other stuff
}
for
时工作正常循环,我已经测试了很多次。此外,
i
没有特定的值。或
j
为其抛出异常。有时是
8, 6
其他时候它可以是任何东西,比如
19,2
或任何东西。此外,在
Parallel
循环
+1
没有像
msdn 那样造成任何损害文件说它是排他性的而不是包容性的。此外,如果这是问题,我只会在最后一个索引(i 的最后一个值)处出现异常,但事实并非如此。
dr = dt.Rows.Add();
lock(lockObject) {
dr = dt.Rows.Add();
}
ArgumentOutOfRangeException
,如果我在调试窗口中运行它,它仍然可以正常工作。
System.ArgumentOutOfRangeException was unhandled by user code
HResult=-2146233086
Message=Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Source=mscorlib
ParamName=index
StackTrace:
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at System.Data.RecordManager.NewRecordBase()
at System.Data.DataTable.NewRecordFromArray(Object[] value)
at System.Data.DataRowCollection.Add(Object[] values)
at AdminEntity.BAL.Service.ExcelImportServices.<>c__DisplayClass2e.<WorksheetToDataTableForInvoiceCTN>b__2d(Int32 i) in C:\Projects\Manager\Admin\AdminEntity\AdminEntity.BAL\Service\ExcelImportServices.cs:line 578
at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
InnerException:
最佳答案
好的。因此,您现有的代码存在一些问题,其中大部分已被其他人触及:
Parallel.For(0, 10, (i) => { Console.WriteLine(i); });
,前四个线程(在四核系统上)将与 i
一起排队值 0-3。但是这些线程中的任何一个都可能在任何其他线程之前开始或完成执行。因此,您可能会首先看到 2 打印,因此线程 4 将排队。然后线程 1 可能完成,线程 5 将排队。然后线程 4 可能会完成,甚至在线程 0 或 3 完成之前。等等,等等。 TL;DR:你不能假设并行的有序输出。 ??
清理字符串格式。 ,它评估前面的值是否为空,如果是,则分配后续值。例如,foo = bar ?? ""
相当于 if (bar == null) { foo = ""; } else { foo = bar; }
. private void ReadIntoTable(ExcelWorksheet sheet)
{
DataTable dt = new DataTable(sheet.Name);
int height = sheet.Dimension.Rows;
int width = sheet.Dimension.Columns;
for (int j = 1; j <= width; j++)
{
string colText = (sheet.Cells[1, j].Value ?? "").ToString();
dt.Columns.Add(colText);
}
for (int i = 2; i <= height; i++)
{
dt.Rows.Add();
}
Parallel.For(1, height, (i) =>
{
var row = dt.Rows[i - 1];
for (int j = 0; j < width; j++)
{
string str = (sheet.Cells[i + 1, j + 1].Value ?? "").ToString();
row[j] = str;
}
});
// convert to your special Excel data model
// ...
}
dr[j - 1] = excelWorksheet.Cells[i, j].Value != null ? excelWorksheet.Cells[i, j].Value.ToString() : null;
并将其分成几部分,我们可以确切地看到它失败的部分。它在
row[j] = str;
上失败了,我们实际将文本写入行的位置。
Thread Safety
This type is safe for multithreaded read operations. You must synchronize any write operations.
private static object s_lockObject = "";
private void ReadIntoTable(ExcelWorksheet sheet)
{
// ...
lock (s_lockObject)
{
row[j] = str;
}
// ...
}
for (int i = 1; i < height; i++)
大约需要 3.5s。我的猜测是,由于锁仅用于写入数据,因此在一个线程上写入数据并在另一个线程上处理文本实现的好处非常小。
string[,] rows = new string[height, width];
Parallel.For(1, height, (i) =>
{
for (int j = 0; j < width; j++)
{
rows[i - 1, j] = (sheet.Cells[i + 1, j + 1].Value ?? "").ToString();
}
});
关于c# - 使用 ParallelFor 循环时索引超出范围异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29541767/
在过去的一天里,我一直在努力为这种方式找到一个好的解决方案,并想听听你的想法。 我有一个接收大型动态 JSON 数组(仅包含字符串化对象)的管道, 我需要能够为该数组中的每个条目创建一个 Contai
在抛出 OperationCancelledException 之前,代码总是等到当前正在运行的任务完成。 我希望程序在条件为真时立即停止。 static void Main() { // w
这是一个非常奇怪的情况,首先是代码...... 编码 private List WorksheetToDataTableForInvoiceCTN(ExcelWorksheet excelWorks
我有以下 C# 代码片段: using System; class count { public static void Main() { int [] a = {-30, 30, -20,
从 Kubeflow Pipeline kfp.Parallel For 聚合结果的好模式是什么? 最佳答案 目前可能不支持: Support inputs with multiple argumen
我是一名优秀的程序员,十分优秀!