Основной поток завершен.
Как видите, выполнение потоков завершилось после возврата из последовательного ряда вызовов метода Join().
Передача аргумента потоку
Первоначально в среде .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