Работает не так как ожидалось C# Threading

Рейтинг: 0Ответов: 1Опубликовано: 11.04.2023

Код готов к запуску. Возвращает не то что ожидается. Ожидается двумерный в первом уровне многомерного. Но работает только с костылём и возвращает немного не то. Я думаю по коду больше видно что я хотел. В отладчике будет неожиданный выход заграницы objArray без костыля.

using System;
using System.Threading;

namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {

            int[] arr = { 4, 5, 6, 2 };
            int[] arr2 = { 4, 5, 6, 2 };

            int n = 2;
            int step = arr.Length / n;

            // Создаем массив для хранения результатов обработки каждой части массива
            
            int[][][] objArray = new int[n][][];// ЕСЛИ ЗАМЕНИТЬ ТУТ n НА n+1 ТО РАБОТАЕТ, НО 
            // НА ВЫХОДЕ ОБЬЕКТ С ТРЕМЯ ЭЛЕМЕНТАМИ ВМЕСТО 2

            // Создаем потоки для каждой части массива и запускаем их параллельно
            Thread[] threads = new Thread[n];
            for (int pIndex = 0; pIndex < n; pIndex++)
            {

                Console.WriteLine(pIndex);
                int startIdx = pIndex * step;
                int endIdx = (pIndex + 1) * step - 1;
                threads[pIndex] = new Thread(() => {
                    // Выполняем операции над текущей частью массива
                    int[][] result = DoSomething();
                    // Сохраняем результат в массив результатов
                    objArray[pIndex] = result; 

                });
                threads[pIndex].Start();
            }

            // Ждем завершения всех потоков
            foreach (Thread thread in threads)
            {
                thread.Join();
            }


            static int[][] DoSomething(){
                int[][] numbers = new int[3][];
                numbers[0] = new int[] { 1, 2, 3 };
                numbers[1] = new int[] { 4, 5, 6, 7 };
                numbers[2] = new int[] { 8, 9 };
                return numbers;
            }


        }
    }
}

Ответы

▲ 2Принят

Проблема заключается в том, что вы пытаетесь обратиться к элементу массива objArray, который еще не был инициализирован. В данном случае вы создаете массив objArray с размером n, но каждый элемент этого массива должен быть инициализирован как двумерный массив. Однако, вы не инициализируете каждый элемент массива objArray как двумерный массив. Вы можете инициализировать каждый элемент objArray при создании массива, как показано ниже:

int[][][] objArray = new int[n][][];
for (int i = 0; i < n; i++)
{
    objArray[i] = new int[3][];
}

Это создаст массив objArray с n элементами, каждый из которых будет инициализирован как двумерный массив размером 3 на n (т.е. каждый элемент будет представлять собой 3 строки и n столбцов). Затем, внутри цикла, вы можете сохранять результат DoSomething в соответствующий элемент objArray:

threads[pIndex] = new Thread(() => {
    // Выполняем операции над текущей частью массива
    int[][] result = DoSomething();
    // Сохраняем результат в массив результатов
    objArray[pIndex] = result; 
});

Теперь вы можете получить доступ к результатам, сохраненным в objArray, вне цикла потока. Например, вы можете вывести все элементы objArray на консоль следующим образом:

foreach (int[][] array2D in objArray)
{
    foreach (int[] array1D in array2D)
    {
        foreach (int num in array1D)
        {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }
    Console.WriteLine();
}

UP

        int[] arr = { 4, 5, 6, 2 };
        int[] arr2 = { 4, 5, 6, 2 };

        int n = 2;
        int step = arr.Length / n;

        int[][][] objArray = new int[n][][];

        Thread[] threads = new Thread[n];
        for (int pIndex = 0; pIndex < n; pIndex++)
        {
            int currentIndex = pIndex; // Создаем временную переменную
            Console.WriteLine(pIndex);
            int startIdx = currentIndex * step;
            int endIdx = (currentIndex + 1) * step - 1;
            threads[currentIndex] = new Thread(() => {
                int[][] result = DoSomething();
                objArray[currentIndex] = result; // Используем временную переменную
            });
            threads[currentIndex].Start();
        }

        // Ждем завершения всех потоков
        foreach (Thread thread in threads)
        {
            thread.Join();
        }


        static int[][] DoSomething(){
            int[][] numbers = new int[3][];
            numbers[0] = new int[] { 1, 2, 3 };
            numbers[1] = new int[] { 4, 5, 6, 7 };
            numbers[2] = new int[] { 8, 9 };
            return numbers;
        }

Попробуй так.