Полное руководство по языку программирования С# 14 и платформе .NET 10 / Многопоточность

Потоки с параметрами и ParameterizedThreadStart

Начальный ⏱ 3 мин чтения 👁 2 🕓 обновлено 11.08.2026

В предыдущей статье было рассмотрено, как запускать в отдельных потоках методы без параметров. А что, если нам надо передать какие-нибудь параметры в поток?

Для этой цели используется делегат ParameterizedThreadStart, который передается в конструктор класса Thread:

public delegate void ParameterizedThreadStart(object? obj);

Применение делегата ParameterizedThreadStart во многом похоже на работу с ThreadStart. Рассмотрим на примере:


using System.Threading;

// создаем новые потоки
Thread myThread1 = new Thread(new ParameterizedThreadStart(Print));
Thread myThread2 = new Thread(Print);
Thread myThread3 = new Thread(message => Console.WriteLine(message));

// запускаем потоки
myThread1.Start("Hello");
myThread2.Start("Привет");
myThread3.Start("Salut");


void Print(object? message) => Console.WriteLine(message);

При создании потока в конструктор класса Thread передается объект делегата ParameterizedThreadStart new Thread(new ParameterizedThreadStart(Print)), либо непосредственно метод, который соответствует этому делегату (new Thread(Print)), в том числе в виде лямбда-выражения (new Thread(message => Console.WriteLine(message)))

Затем при запуске потока в метод Start() передается значение, которое передается параметру метода Print. И в данном случае мы получим следующий консольный вывод:

Salut
Hello
Привет

При использовании ParameterizedThreadStart мы сталкиваемся с ограничением: мы можем запускать во втором потоке только такой метод, который в качестве единственного параметра принимает объект типа object?. Поэтому если мы хотим использовать данные других типов, в самом методе необходимо выполнить приведение типов. Например:


using System.Threading;

int number = 4;
// создаем новый поток
Thread myThread = new Thread(Print);
myThread.Start(number);    // n * n = 16


// действия, выполняемые во втором потокке
void Print(object? obj)
{
    // здесь мы ожидаем получить число
    if (obj is int n)
    {
        Console.WriteLine($"n * n = {n * n}");
    }
}

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

Но что делать, если нам надо передать не один, а несколько параметров различного типа? В этом случае можно определить свои типы:


using System.Threading;

Person tom = new Person("Tom", 37);
// создаем новый поток
Thread myThread = new Thread(Print);
myThread.Start(tom);

void Print(object? obj)
{
    // здесь мы ожидаем получить объект Person
    if (obj is Person person)
    {
        Console.WriteLine($"Name = {person.Name}");
        Console.WriteLine($"Age = {person.Age}");
    }
}

record class Person(string Name, int Age);

Сначала определяем специальный класс Person, объект которого будет передаваться во второй поток, а в методе Main передаем его во второй поток.

Но тут опять же есть одно ограничение: метод Thread.Start не является типобезопасным, то есть мы можем передать в него любой тип, и потом нам придется приводить переданный объект к нужному нам типу. Для решения данной проблемы рекомендуется объявлять все используемые методы и переменные в специальном классе, а в основной программе запускать поток через ThreadStart. Например:


using System.Threading;

Person tom = new Person("Tom", 37);
// создаем новый поток
Thread myThread = new Thread(tom.Print);
myThread.Start();

record class Person(string Name, int Age)
{
    public void Print()
    {
        Console.WriteLine($"Name = {Name}");
        Console.WriteLine($"Age = {Age}");
    }
}

Проверь себя

📋 Тест по теме «Потоки с параметрами и ParameterizedThreadStart» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

public _____ void ParameterizedThreadStart(object? obj);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

using System._____;

// создаем новые потоки
Thread myThread1 = new Thread(new ParameterizedThreadStart(Print));
Thread myThread2 = new Thread(Print);
Thread myThread3 = new Thread(message => Console.WriteLine(message));

// запускаем потоки
myThread1.Start("Hello");
myThread2.Start("Привет");
myThread3.Start("Salut");


void Print(object? message) => Console.WriteLine(message);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

using System.Threading;

int _____ = 4;
// создаем новый поток
Thread myThread = new Thread(Print);
myThread.Start(number);    // n * n = 16


// действия, выполняемые во втором потокке
void Print(object? obj)
{
    // здесь мы ожидаем получить число
    if (obj is int n)
    {
        Console.WriteLine($"n * n = {n * n}");
    }
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

using System.Threading;

Person _____ = new Person("Tom", 37);
// создаем новый поток
Thread myThread = new Thread(Print);
myThread.Start(tom);

void Print(object? obj)
{
    // здесь мы ожидаем получить объект Person
    if (obj is Person person)
    {
        Console.WriteLine($"Name = {person.Name}");
        Console.WriteLine($"Age = {person.Age}");
    }
}

record class Person(string Name, int Age);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

using System.Threading;

Person tom = _____ Person("Tom", 37);
// создаем новый поток
Thread myThread = new Thread(tom.Print);
myThread.Start();

record class Person(string Name, int Age)
{
    public void Print()
    {
        Console.WriteLine($"Name = {Name}");
        Console.WriteLine($"Age = {Age}");
    }
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

public delegate void _____(_____? obj);
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

using System._____ing;

// создаем новые потоки
Thread myThread1 = new Thread(new ParameterizedThreadStart(Print));
Thread myThread2 = new Thread(Print);
Thread myThread3 = new Thread(message => Console.WriteLine(message));

// запускаем потоки
myThread1.Start("_____");
myThread2.Start("Привет");
myThread3.Start("Salut");


void Print(object? message) => Console.WriteLine(message);
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Потоки с параметрами и ParameterizedThreadStart»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Потоки с параметрами и ParameterizedThreadStart», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

public delegate void ParameterizedThreadStart(object? obj);
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Потоки с параметрами и ParameterizedThreadStart»
+30 XP

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

using System.Threading;

// создаем новые потоки
Thread myThread1 = new Thread(new ParameterizedThreadStart(Print));
Thread myThread2 = new Thread(Print);
Thread myThread3 = new Thread(message => Console.WriteLine(message));

// запускаем потоки
myThread1.Start("Hello");
myThread2.Start("Привет");
myThread3.Start("Salut");


void Print(object? message) => Console.WriteLine(message);
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Потоки с параметрами и ParameterizedThreadStart»
+50 XP

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

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Потоки с параметрами и ParameterizedThreadStart»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Потоки с параметрами и ParameterizedThreadStart». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

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

Обсуждение (0)

Войдите, чтобы оставить комментарий.