При вызове tasksInFlight.Add(updateDt(index, "col " + index));
значение индекса не читается; вы просто сохраняете задачу, которая будет выполнена позже - когда вы вызываете Task.WhenAll
. Это когда задачи выполняются, когда оценивается значение index
. Что происходит после окончания l oop и значения index
теперь равного dt.Columns.Count
, что выходит за пределы диапазона массива.
Подробнее о C# замыканиях здесь .
Чтобы исправить это, вы можете сделать так:
for (int index = 0; index < dt.Columns.Count; index++)
{
int tmpIndex = index;
tasksInFlight.Add(updateDt(tmpIndex, "col " + tmpIndex));
}
РЕДАКТИРОВАТЬ : После дальнейшего изучения выясняется, что DataTable не поточно-ориентированный.
В дополнение к вышеприведенному исправлению к DataTable следует обращаться в блокировке:
lock (dt)
{
dt.Rows[i][colNum] = data;
}
Однако, если только не извлекаются фактические данные для помещения в интенсивную ЦП DataTable блокировка исключает все преимущества параллелизма в этом случае.