Книга: 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().

Оглавление книги


Генерация: 4.044. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз