Благодаря этому методmt. Run() выполняется в своем собственном потоке. После вызова методаStart () выполнение основного потока возвращается к методуMain (),где начинается циклdo-while.Оба потока продолжают выполняться, совместно используя ЦП, вплоть до окончания цикла. Ниже приведен результат выполнения данной программы. (Он может отличаться в зависимости от среды выполнения, операционной системы и степени загрузки задач.)
Основной поток начат.
Потомок #1 начат.
Потомок #1 завершен.
Основной поток завершен.
Зачастую в многопоточной программе требуется, чтобы основной поток был последним потоком, завершающим ее выполнение. Формально программа продолжает выполняться до тех пор, пока не завершатся все ее приоритетные потоки. Поэтому требовать, чтобы основной поток завершал выполнение программы, совсем не обязательно. Тем не менее этого правила принято придерживаться в многопоточном программировании, поскольку оно явно определяет конечную точку программы. В рассмотренной выше программе предпринята попытка сделать основной поток завершающим ее выполнение. Для этой цели значение переменнойCountпроверяется в циклеdo-whileвнутри методаMain (), и как только это значение оказывается равным 10, цикл завершается и происходит поочередный возврат из методов Sleep (). Но такой подход далек от совершенства, поэтому далее в этой главе будут представлены более совершенные способы организации ожидания одного потока до завершения другого.
Простые способы усовершенствования многопоточной программы
Рассмотренная выше программа вполне работоспособна, но ее можно сделать более эффективной, внеся ряд простых усовершенствований, (to-первых, можно сделать так, чтобы выполнение потока начиналось сразу же после его создания. Для этого достаточно получить экземпляр объекта типаThreadв конструкторе классаMyThread.И во-вторых, в классеMyThreadсовсем не обязательно хранить имя потока, поскольку для этой цели в классеThreadспециально определено свойствоName.
public string Name { get; set; }
СвойствоNameдоступно для записи и чтения и поэтому может служить как для запоминания, так и для считывания имени потока.
Ниже приведена версия предыдущей программы, в которую внесены упомянутые выше усовершенствования.
// Другой способ запуска потока.
using System;
using System.Threading;
class MyThread { public int Count; public Thread Thrd;
public MyThread(string name) {
Count = 0;
Thrd = new Thread(this.Run);
Thrd.Name = name; // задать имя потока Thrd.Start(); // начать поток
}
// Точка входа в поток, void Run() {