Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Многопоточность.doc
Скачиваний:
4
Добавлен:
28.10.2018
Размер:
225.79 Кб
Скачать

Ожидание завершения потока

Класс Thread предоставляет только синхронные методы ожидания завершения потока. Первый из них – свойство IsAlive:

while (trd.IsAlive)

{ continue; }

Внутри данного цикла вы можете делать какую-либо работу. Другой подход – использование метода Join.

trd.Join();

Вызов этого метода блокирует вызвавший его поток до тех пор, пока поток trd не закончит свою работу.

Недостатком этого метода несомненно является блокирование основного потока. К сожалению класс Thread не предоставляет возможности узнать о завершении работы потока с помощью делегата обратного вызова.

Управление выполнением потока

Класс Thread предоставляет возможности приостановить выполнение потока, снова запустить его и совсем прервать поток. Рассмотрим их. Приостановка и продолжение выполнения потока осуществляются вызовом методов Suspend и Resume. Следует отметить, что Microsoft считает эти методы устаревшими и не рекомендует их использовать. Поэтому вам не следует прибегать к их услугам без крайней необходимости. Данные методы вызывают исключение в случае если поток не запущен или уже завершен. Так же метод Resume вызывает исключение в случае, если поток не приостановлен методом Suspend.

Более сложно обстоит дело с прерыванием работы потока. В реальных приложениях поток выполняет некоторую работу, т.е. он изменяет данные. Если прервать его неожиданно, то данные могут оказаться в нерабочем состоянии. Поэтому .NET реализует механизм, уведомляющий поток о том, что его хотят досрочно завершить. Дело программиста – завершить поток правильно.

Первый метод, который прерывает поток – Abort.

trd.Abort();

Вызов этого метода приводит к генерации в соответствующем потоке исключения ThreadAbortException. Задача программиста – обработать его и правильно завершить поток:

private static void CheckPrimeNumberWithAbort()

{

try

{

}

catch (ThreadAbortException)

{

Console.WriteLine("Thread is aborted");

}

}

Особенностью, о которой следует знать, является то, что вызов метода Abort, когда нить находится в приостановленном состоянии приводит к появлению исключения. Поэтому вам придется вызвать Resume перед использованием Abort.

Вторым методом, который прерывает работу нити, является метод Interrupt. Его отличие от Abort заключается в том, что он прерывает работу не любого потока, а только того, который находится в состоянии ожидания (например, ожидает завершения работы другого потока, вызвав его метод Join) или «спит». Последний термин будет подробнее рассмотрен ниже. Если же поток не находится в таком состоянии, метод Interrupt ничего не сделает. Таким образом Interrupt прерывает скорее «сон» или ожидание потока, чем его самого. При этом в самом потоке возникает исключение ThreadInterruptedException, которое вы можете обработать.

«Сон» потока

Настало время рассмотреть, что же такое – «сон» потока. Статический метод Sleep класса Thread заставляет вызвавший его поток «заснуть». Т.е. то время, которое указано в параметре метода, поток не будет работать, ему не будут передаваться кванты времени. Как же это реализуется? Как уже говорилось выше, операционная система поддерживает список активных потоков. Но кроме него существует еще и список спящих потоков. Вызов метода Sleep помещает поток в этот список. Потоки в этом списке не участвуют в распределении квантов времени. Они ждут завершения времени своего сна. После этого поток снова перемещается в список активных потоков.

Вы можете вызывать метод Sleep для ожидания какого-либо события, хотя существуют методы лучше. О них мы будет говорить далее.

Единственным исключением из описанного механизма работы метода Sleep является его вызов с параметром 0. В этом случае поток не перемещается в список спящих потоков. Просто его выполнение немедленно прерывается и его квант времени передается другому потоку. Но поток попрежнему остается в списке активных потоков и участвует в распределении времени.