Добавить в цитаты Настройки чтения

Страница 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(&quot;У основного потока нет имени.&quot;);</b>

<b>    else</b>

<b>      Console.WriteLine(&quot;Основной поток называется: &quot; + Thrd.Name);</b>

<b>    // Отобразить приоритет основного потока.</b>

<b>    Console.WriteLine(&quot;Приоритет: &quot; + Thrd.Priority);</b>

<b>    Console.WriteLine();</b>

<b>    // Установить имя и приоритет.</b>

<b>    Console.WriteLine(&quot;Установка имени и приоритета.&quot;);</b>

<b>    Thrd.Name = &quot;Основной Поток&quot;;</b>

<b>    Thrd.Priority = ThreadPriority.AboveNormal;</b>

<b>    Console. WriteLine (&quot;Теперь основной поток называется: &quot; +</b>

<b>      Thrd.Name);</b>

<b>    Console.WriteLine(&quot;Теперь приоритет: &quot; + Thrd.Priority);</b>

<b>  }</b>

<b>}</b>

Ниже приведен результат выполнения этой программы.

<b>У основного потока нет имени.</b>

<b>Приоритет: Normal</b>

<b>Установка имени и приоритета.</b>

<b>Теперь основной поток называется: Основной Поток</b>

<b>Теперь приоритет: AboveNormal</b>

Следует, однако, быть очень внимательным, выполняя операции с основным потоком. Так, если добавить в конце метода Main() следующий вызов метода Join():