Книга: C# 4.0: полное руководство
Передача аргумента потоку
Передача аргумента потоку
Первоначально в среде .NET Framework нельзя было передавать аргумент потоку, когда он начинался, поскольку у метода, служившего в качестве точки входа в поток, не могло быть параметров. Если же потоку требовалось передать какую-то информацию, то к этой цели приходилось идти различными обходными путями, например использовать общую переменную. Но этот недостаток был впоследствии устранен, и теперь аргумент может быть передан потоку. Для этого придется воспользоваться другими формами метода Start()
, конструктора класса Thread
, а также метода, служащего в качестве точки входа в поток.
Аргумент передается потоку в следующей форме метода Start()
.
public void Start(object параметр)
Объект, указываемый в качестве аргумента параметр, автоматически передается методу, выполняющему роль точки входа в поток. Следовательно, для того чтобы передать аргумент потоку, достаточно передать его методу Start()
.
Для применения параметризированной формы метода Start()
потребуется следующая форма конструктора класса Thread
:
public Thread(ParameterizedThreadStart запуск)
где запуск обозначает метод, вызываемый с целью начать выполнение потока. Обратите внимание на то, что в этой форме конструктора запуск имеет тип ParameterizedThreadStart
, а не ThreadStart
, как в форме, использовавшейся в предыдущих примерах. В данном случае ParameterizedThreadStart
является делегатом, объявляемым следующим образом.
public delegate void ParameterizedThreadStart(object obj)
Как видите, этот делегат принимает аргумент типа object
. Поэтому для правильного применения данной формы конструктора класса Thread
у метода, служащего в качестве точки входа в поток, должен быть параметр типа object
.
В приведенном ниже примере программы демонстрируется передача аргумента потоку.
// Пример передачи аргумента методу потока.
using System;
using System.Threading;
class MyThread {
public int Count;
public Thread Thrd;
// Обратите внимание на то, что конструктору класса
// MyThread передается также значение типа int.
public MyThread(string name, int num) {
Count = 0;
// Вызвать конструктор типа ParameterizedThreadStart
// явным образом только ради наглядности примера.
Thrd = new Thread(this.Run);
Thrd.Name = name;
// Здесь переменная num передается методу Start()
// в качестве аргумента.
Thrd.Start(num);
}
// Обратите внимание на то, что в этой форме метода Run()
// указывается параметр типа object.
void Run(object num) {
Console.WriteLine(Thrd.Name + " начат со счета " + num);
do {
Thread.Sleep (500);
Console.WriteLine("В потоке " + Thrd.Name +
", Count = " + Count);
Count++;
} while(Count < (int) num);
Console.WriteLine(Thrd.Name + " завершен.");
}
}
class PassArgDemo {
static void Main() {
// Обратите внимание на то, что число повторений
// передается этим двум объектам типа MyThread.
MyThread mt = new MyThread("Потомок #1", 5);
MyThread mt2 = new MyThread("Потомок #2", 3);
do {
Thread.Sleep(100);
} while (mt.Thrd.IsAlive ||
mt2.Thrd.IsAlive);
Console.WriteLine("Основной поток завершен.");
}
}
Ниже приведен результат выполнения данной программы, хотя у вас он может оказаться несколько иным.
Потомок #1 начат со счета 5
Потомок #2 начат со счета 3
В потоке Потомок #1, Count = 0
В потоке Потомок #2, Count = 0
В потоке Потомок #1, Count = 1
В потоке Потомок #2, Count = 1
В потоке Потомок #1, Count = 2
В потоке Потомок #2, Count = 2
Потомок #2 завершен.
В потоке Потомок #1, Count = 3
В потоке Потомок #1, Count = 4
Потомок #1 завершен.
Основной поток завершен.
Как следует из приведенного выше результата, первый поток повторяется пять раз, а второй — три раза. Число повторений указывается в конструкторе класса MyThread
и затем передается методу Run()
, служащему в качестве точки входа в поток, с помощью параметризированной формы ParameterizedThreadStart
метода Start()
.
- Основы многопоточной обработки
- Класс Thread
- Определение момента окончания потока
- Передача аргумента потоку
- Свойство IsBackground
- Приоритеты потоков
- Синхронизация
- Сообщение между потоками с помощью методов Wait(), Pulse() и PulseAll()
- Взаимоблокировка и состояние гонки
- Применение атрибута MethodlmplAttribute
- Применение мьютекса и семафора
- Применение событий
- Класс Interlocked
- Классы синхронизации, внедренные в версии .NET Framework 4.0
- Прерывание потока
- Приостановка и возобновление потока
- Определение состояния потока
- Применение основного потока
- Дополнительные средства многопоточной обработки, внедренные в версии .NET Framework 4.0
- Рекомендации по многопоточному программированию
- Запуск отдельной задачи
- 4.1.1. Передача данных потоку
- Передача прав
- 6.4.2. Передача номенклатурных позиций между ячейками склада
- Глава 11 Передача во временное пользование и заказы
- Глава 10 Передача файлов
- 5.3.8. Защищенная передача данных
- 10.1.3. Передача файлов
- Доступ к потоку
- Передача параметров
- Несколько слов о словах, буквах и аргументах
- 2.1. Соглашения по опциям и аргументам
- 10.6.7. Передача сигналов: kill() и killpg()