Страница 420 из 502
Приостановка и возобновление потока
В первоначальных версиях среды .NET Framework поток можно было приостановить вызовом метода Thread.Suspend() и возобновить вызовом метода Thread.Resume(). Но теперь оба эти метода считаются устаревшими и не рекомендуются к применению в новом коде. Объясняется это, в частности, тем, что пользоваться методом Suspend() на самом деле небезопасно, так как с его помощью можно приостановить поток, который в настоящий момент удерживает блокировку, что препятствует ее снятию, а следовательно, приводит к взаимоблокировке. Применение обоих методов может стать причиной серьезных осложнений на уровне системы. Поэтому для приостановки и возобновления потока следует использовать другие средства синхронизации, в том числе мьютекс и семафор.
Определение состояния потока
Состояние потока может быть получено из свойства Threadstate, доступного в классе Thread. Ниже приведена общая форма этого свойства.
<b>public ThreadState ThreadState{ get; }</b>
Состояние потока возвращается в виде значения, определенного в перечислении ThreadState. Ниже приведены значения, определенные в этом перечислении.
<b>ThreadState.Aborted</b>
<b>ThreadState.AbortRequested</b>
<b>ThreadState.Background</b>
<b>ThreadState.Ru
<b>ThreadState.Stopped</b>
<b>ThreadState.StopRequested</b>
<b>ThreadState.Suspended</b>
<b>ThreadState.SuspendRequested</b>
<b>ThreadState.Unstarted</b>
<b>ThreadState.WaitSleepJoin</b>
Все эти значения не требуют особых пояснений, за исключением одного. Значение ThreadState.WaitsleepJoin обозначает состояние, в которое поток переходит во время ожидания в связи с вызовом метода Wait(), Sleep() или Join().
Применение основного потока
Как пояснялось в самом начале этой главы, у всякой программы на C# имеется хотя бы один поток исполнения, называемый основным. Этот поток программа получает автоматически, как только начинает выполняться. С основным потоком можно обращаться таким же образом, как и со всеми остальными потоками.
Для доступа к основному потоку необходимо получить объект типа Thread, который ссылается на него. Это делается с помощью свойства CurrentThread, являющегося членом класса Thread. Ниже приведена общая форма этого свойства.
Данное свойство возвращает ссылку на тот поток, в котором оно используется. Поэтому если свойство CurrentThread используется при выполнении кода в основном потоке, то с его помощью можно получить ссылку на основной поток. Имея в своем распоряжении такую ссылку, можно управлять основным потоком так же, как и любым другим потоком.
В приведенном ниже примере программы сначала получается ссылка на основной поток, а затем получаются и устанавливаются имя и приоритет основного потока.
<b>// Продемонстрировать управление основным потоком.</b>
<b>using System;</b>
<b>using System.Threading;</b>
<b>class UseMain {</b>
<b> static void Main() {</b>
<b> Thread Thrd;</b>
<b> // Получить основной поток.</b>
<b> Thrd = Thread.CurrentThread;</b>
<b> // Отобразить имя основного потока,</b>
<b> if(Thrd.Name == null)</b>
<b> Console.WriteLine("У основного потока нет имени.");</b>
<b> else</b>
<b> Console.WriteLine("Основной поток называется: " + Thrd.Name);</b>
<b> // Отобразить приоритет основного потока.</b>
<b> Console.WriteLine("Приоритет: " + Thrd.Priority);</b>
<b> Console.WriteLine();</b>
<b> // Установить имя и приоритет.</b>
<b> Console.WriteLine("Установка имени и приоритета.");</b>
<b> Thrd.Name = "Основной Поток";</b>
<b> Thrd.Priority = ThreadPriority.AboveNormal;</b>
<b> Console. WriteLine ("Теперь основной поток называется: " +</b>
<b> Thrd.Name);</b>
<b> Console.WriteLine("Теперь приоритет: " + Thrd.Priority);</b>
<b> }</b>
<b>}</b>
Ниже приведен результат выполнения этой программы.
<b>У основного потока нет имени.</b>
<b>Приоритет: Normal</b>
<b>Установка имени и приоритета.</b>
<b>Теперь основной поток называется: Основной Поток</b>
<b>Теперь приоритет: AboveNormal</b>
Следует, однако, быть очень внимательным, выполняя операции с основным потоком. Так, если добавить в конце метода Main() следующий вызов метода Join():