Suspend и Resume

Поток может быть явно приостановлен и продолжен с помощью методов Thread.Suspend и Thread.Resume. Это механизм никак не пересекается с блокировками, обсуждаемыми ранее. Обе системы независимы и работают параллельно.

Поток может приостановить себя или другой поток. Вызов Suspend переводит поток на короткое время в состояние SuspendRequested, а затем, при достижении безопасной точки для сбора мусора – в состояние Suspended. Из этого состояния поток может продолжить выполнение только с помощью другого потока, который вызовет для него метод Resume. Resume работает только для приостановленных, но не для заблокированных потоков.

В.NET 2.0 Suspend и Resume объявлены не рекомендованными к применению из-за опасности произвольной приостановки другого потока. Если поток, удерживающий блокировку на критическом ресурсе, будет приостановлен, может зависнуть целое приложение (или компьютер). Это намного опаснее вызова Abort – который привел бы к освобождению всех блокировок – по крайней мере, теоретически – на основании кода в блоках finally.

Можно, однако, безопасно вызывать Suspend для текущего потока, реализовав при этом простой механизм синхронизации для рабочего потока в цикле выполнение задачи/вызов Suspend для себя/ожидание вызова Resume (“побудки”) главным потоком, когда будет готова следующая задача. Сложность заключается в определении, действительно ли рабочий поток сейчас приостановлен. Посмотрите следующий код:

worker.NextTask = "MowTheLawn"; if ((worker.ThreadState & ThreadState.Suspended) > 0) worker.Resume(); else // Нельзя вызывать Resume, так как поток уже выполняется. // Посигналим рабочему потоку флагом: worker.AnotherTaskAwaits = true;

Это грубейшее нарушение потоковой безопасности – код может быть вытеснен в любой точке этих пяти строк, и пока он будет ожидать своего кванта времени, рабочий поток будет исполняться и может изменить свое состояние. Несмотря на то, что разрулить эту ситуацию можно, решение будет более сложным, чем его альтернатива – использование конструкций сигнализации, таких как AutoResetEvent или Monitor.Wait. Это делает Suspend и Resume совершенно бесполезными.

Нерекомендуемые методы Suspend и Resume имеют два режима – опасный и бесполезный.

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: