Шаг 238.
Язык программирования C#. Начала.
Многопоточное программирование. Использование потоков

    На этом шаге мы рассмотрим программу, где создается несколько дочерних потоков.

    На следующих шагах мы рассмотрим различные способы создания потоков в программе. Еще одна программа иллюстрирует подход, при котором в программе создается несколько дочерних потоков, причем на этот раз программный код потоков реализуется на основе нестатических методов. Рассмотрим приведенный ниже код.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

namespace pr238_1
{
    // Класс с методом для выполнения в потоке: 
    class MyClass {
        // Количество сообщений: 
        private int count;
        // Время задержки между сообщениями: 
        private int time;
        // Текст для отображения: 
        private string text;
        // Метод для выполнения в потоке: 
        public void show() {
            Console.WriteLine(text + ": Начало..."); 
            for(int i = 1; i <= count; i++) {
                // Отображение сообщения:
                Console.WriteLine(text + " -> " + i);
                // Задержка в выполнении потока:
                Thread.Sleep(time);
            }
            Console.WriteLine(text + ": Завершение...");
        }
        // Конструктор:
        public MyClass(int c, int t, string txt) { 
            count = c; 
            time = t; 
            text = txt;
        }
    }

    // Главный класс: 
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Главный поток: Начало...");
            // Создание объектов:
            MyClass objA = new MyClass(5, 2000, "Поток A");
            MyClass objB = new MyClass(6, 1200, "Поток B");
            MyClass objC = new MyClass(8, 1000, "Поток C");
            // Создание объектов потоков:
            Thread A = new Thread(objA.show);
            Thread B = new Thread(objB.show);
            Thread C = new Thread(objC.show);
            // Запуск дочерних потоков:
            A.Start();
            B.Start();
            C.Start();
            Console.WriteLine("Главный поток: Завершение...");
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Ниже показан возможный результат выполнения программы:


Рис.1. Результат работы приложения

    В этой программе в главном потоке создаются три дочерних потока. Дочерние потоки создаются на основе нестатического метода show(), описанного в классе MyClass. У класса MyClass есть:

    Значения полей передаются аргументами конструктору при создании объекта и используются в методе show(). В теле конструктора командой

  SPAN CLASS="tp_oop">Console.WriteLine(text + ": Начало..."); 
выводится сообщение о начале выполнения метода (потока). Затем запускается конструкция цикла (количество итераций цикла определяется значением поля count), и на каждой итерации командой
  Console.WriteLine(text + " -> " + i);
отображается сообщение. Для задержки в выполнении потока использована команда
  Thread.Sleep(time);    . 

    После завершения цикла командой

  Console.WriteLine(text + ": Завершение...");
отображается сообщение о завершении выполнения метода (и, следовательно, потока).

    В главном методе отображается сообщение о начале выполнения главного потока (команда

  Console.WriteLine("Главный поток: Начало...");
). Далее создаются три объекта objA, objB и objC класса MyClass. Это "обычные" объекты. На их основе создаются объекты дочерних потоков A, B и C. Каждый раз аргументом конструктору класса Thread передается ссылка на метод show() объекта класса MyClass (инструкции objA.show, objB.show и objC.show). Для запуска каждого из потоков на выполнение из объекта потока вызывается метод Start() (команды
  A.Start();     , 
  B.Start(); 
и
  C. Start();
). В результате одновременно с выполнением главного потока в режиме дочерних потоков начинается выполнение кода метода show() из объектов A (первый дочерний поток), B (второй дочерний поток) и C (третий дочерний поток). В это время командой
  Console.WriteLine("Главный поток: Завершение...");
в главном потоке выводится сообщение о завершении потока.


Параметры, влияющие на выполнение потоков, подобраны так, что главный поток завершается раньше дочерних потоков. По умолчанию дочерние потоки являются приоритетными, поэтому продолжают работу даже при завершении главного потока. Позже мы познакомимся с фоновыми потоками, которые автоматически завершаются при завершении главного потока.

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг