На этом шаге мы рассмотрим еще один пример использования потока.
В программе из примера ниже также заполняется двумерный целочисленный массив. Но на этот раз для заполнения массива используется специальный метод. При запуске метода ему передается ссылка на массив (который следует заполнить), индекс строки (начиная с которой заполняется массив) и ссылка на объект для генерирования случайных чисел. Если указанная для заполнения строка массива не является последней, то метод запускает дочерний поток, в котором вызывается этот же метод, но заполнять он должен следующую строку. Таким образом, в результате вызова метода построчно заполняется двумерный массив: начиная с той строки, которая указана при вызове метода, и до последней строки массива включительно. Каждая строка заполняется отдельным потоком.
Теперь рассмотрим программный код, представленный ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace pr246_1 { class Program { // Статический метод для заполнения двумерного массива // случайными числами: static void fill(int[,] a, int k, Random rnd) { // Объектная переменная для потока: Thread t = null; // Если не последняя строка: if (k < a.GetLength(0) - 1) { // Создание объекта потока: t = new Thread(()=>{ // Вызов в потоке метода: fill(a, k + 1, rnd); }); // Запуск потока на выполнение: t.Start(); } // Заполнение строки в массиве: for (int m = 0; m < a.GetLength(1); m++) { // Значение элемента - случайное число: a[k, m] = k * 10 + rnd.Next(10); } // Если объект потока существует и поток еще // выполняется, то необходимо дождаться // завершения потока: if (t != null && t.IsAlive) t.Join(); } // Главный метод: static void Main() { // Создается двумерный массив: int[,] nums = new int[6, 9]; // Объект для генерации случайных чисел: Random rnd = new Random(); // Заполнение массива: fill(nums, 0, rnd); // Отображение содержимого массива: for (int i = 0; i < nums.GetLength(0); i++) { for (int j = 0; j < nums.GetLength(1); j++) { Console.Write("{0,-4}", nums[i, j]); } Console.WriteLine(); } } } }
Результат выполнения программы может быть таким:
Рис.1. Результат работы приложения
В главном классе программы, кроме метода Main(), также описывается статический метод fill() с тремя аргументами:
Ее начальное значение равно null (пустая ссылка). В условной конструкции проверяется условие k<a.GetLength(0)-1, истинное в случае, если обозначенная для заполнения строка не является последней в двумерном массиве. Если так, то создается объект потока и ссылка на этот объект записывается в переменную t. Поток определен таким образом, что при его выполнении вызывается метод fill() (команда
fill(a, k + 1, rnd);
t.Start();
a[k, m] = k * 10 + rnd.Next(10); .
После заполнения строки числами в условной конструкции проверяется условие t != null && t.IsAlive. Если оно истинно, то вследствие команды
t.Join();
В главном методе программы создается двумерный массив nums и объект rnd класса Random для генерации случайных чисел. Массив заполняется при выполнении команды
fill(nums, 0, rnd); ,
На следующем шаге мы закончим изучение этого вопроса.