Куда пропадает содержимое массива при передачи его в промежуточный метод?

Есть метод, производящий некие арифметические операции. В первой половине метода вычисляется массив x, состоящий из расположенных по возрастанию чисел , который передается в промежуточный метод для последующих вычислений.
Код примерно следующий:
{
...
//Это выходные параметры
double[] L; 
double[] V;

...

for (int i = 2; i < n; i++)
{
     FormANk(V, ref d, ref e, ref a, L);
     Value(d, e, a, i + 1, ref L, ref V, epsilon);
}

//t1
if (need)
{
     vr = EV(dA, eA, L);
     ...
}

lam = L;
vec = v;

}

static void Value(double[] d, double[] e, double[] A, int n, ref double[] l, ref double[] v, double epsilon)
{
     double[] L = new double[n];
     double[] V;

     //p1
     Parallel.For(0, n - 2, i =>
     {
          Interlocked.Exchange(ref L[i + 1], EVIn(d, i, A, epsilon));
     });

     EVOut(d, A, ref L);

     V = EVs(A, d, L);

      l = L;
      v = V;
}

private static double[,] EV(double[] d, double[] e, double[] L)
{
     //t2
     int n = d.Length;
     double[,] res = new double[n, n];
     
     //p2       
     Parallel.For(0, n, j =>
     {
          Interlocked.Exchange(ref res[0, j], 1.0d);                
          Interlocked.Exchange(ref res[1, j], (L[j] - d[0]) * res[0, j] / e[0]);
           
          for (int i = 2; i < n; i++)
          {
               Interlocked.Exchange(ref res[i, j], ((L[j] - d[i - 1]) * res[i - 1, j] - e[i - 2] * res[i - 2, j]) / e[i - 1]); ;                   
           }
     });

     Norm(res);

     return res;
}

Здесь t1 и t2 - условное место установки breakpoint.

И что интересно - если последовательно останавливаться на t1, t2 - то все работает верно и без нареканий. Однако, если останавливать выполнение только на t2, то 3 из 7 раз на t2 получаем при просмотре переданного массива x получим примерно следующее {0.0, NaN, 0.0, 0.0, ..., NaN, NaN, 0.0}. Соответственно, если не останавливать выполнение на выходе получим либо требуемый ответ, либо полную белиберду.

Вопрос, как?! Куда пропадают значения и почему только в случае не остановки на t1?

UPD: Однозначно установлено, что если на местах p1 и p2 Parallel.For() заменить на обычный for(), то, вроде бы, данной проблемы не возникает. Тогда вопрос другой - почему так происходит? Заполнение происходит безопасно же. При этом замена внутренних массивов на ConcurrentBag не помогает. Глюк мне все более не понятен.
  • Вопрос задан
  • 2468 просмотров
Пригласить эксперта
Ответы на вопрос 2
Попробуйте поиграться с ParallelOptions.MaxDegreeOfParallelism, а также убедиться, что результат Parallel.For - положительный.
Ответ написан
@genI3 Автор вопроса
Ошибка в коде найдена и не кроется в самом Parallel.For. Однако случайность выполнения/не выполнения кода осталась не ясна.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы