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

Страница 419 из 502

Как следует из приведенного выше результата, значение 100 передается методу Abort() в качестве кода прерывания. Это значение становится затем доступным посредством свойства ExceptionState из класса исключения ThreadAbortException, которое перехватывается потоком при его прерывании.

Запрос на преждевременное прерывание может быть переопределен в самом потоке. Для этого необходимо сначала перехватить в потоке исключение ThreadAbortException, а затем вызвать метод ResetAbort(). Благодаря этому исключается повторное генерирование исключения по завершении обработчика исключения, прерывающего данный поток. Ниже приведена форма объявления метода ResetAbort().

<b>public static void ResetAbort()</b>

Вызов метода ResetAbort() может завершиться неудачно, если в потоке отсутствует надлежащий режим надежной отмены преждевременного прерывания потока.

В приведенном ниже примере программы демонстрируется применение метода ResetAbort().

<b>// Использовать метод ResetAbort().</b>

<b>using System;</b>

<b>using System.Threading;</b>

<b>class MyThread {</b>

<b>  public Thread Thrd;</b>

<b>  public MyThread(string name) {</b>

<b>    Thrd = new Thread(this.Run);</b>

<b>    Thrd.Name = name;</b>

<b>    Thrd.Start();</b>

<b>  }</b>

<b>  // Это точка входа в поток,</b>

<b>  void Run() {</b>

<b>    Console.WriteLine(Thrd.Name + &quot;.начат.&quot;);</b>

<b>    for (int i = 1; i&lt;=1000; i++) {</b>

<b>      try {</b>

<b>        Console.Write(i + &quot; &quot;);</b>

<b>        if((i %10)==0) {</b>

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

<b>          Thread.Sleep(250);</b>

<b>        }</b>

<b>      } catch(ThreadAbortException exc) {</b>

<b>        if((int)exc.ExceptionState ==0) {</b>

<b>          Console.WriteLine(&quot;Прерывание потока отменено! &quot; +</b>

<b>                 &quot;Код завершения &quot; + exc.ExceptionState);</b>

<b>          Thread.ResetAbort();</b>

<b>        }</b>

<b>        else</b>

<b>          Console.WriteLine(&quot;Поток прерван, код завершения &quot;</b>

<b>                + exc.ExceptionState);</b>

<b>      }</b>

<b>    }</b>

<b>    Console.WriteLine(Thrd.Name + &quot; завершен нормально.&quot;);</b>

<b>  }</b>

<b>}</b>

<b>class ResetAbort {</b>

<b>  static void Main() {</b>

<b>    MyThread mt1 = new MyThread(&quot;Мой Поток&quot;);</b>

<b>    Thread.Sleep(1000); // разрешить порожденному потоку начать свое выполнение</b>

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

<b>    mt1.Thrd.Abort(0); // это не остановит поток</b>

<b>    Thread.Sleep(1000); // разрешить порожденному потоку выполняться подольше</b>

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

<b>    mt1.Thrd.Abort(100); // а это остановит поток</b>

<b>    mt1.Thrd.Join(); // ожидать прерывания потока</b>

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

<b>  }</b>

<b>}</b>

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

<b>Мой Поток.начат.</b>

<b>1 2 3 4 5 6 7 8 9 10</b>

<b>11 12 13 14 15 16 17 18 19 20</b>

<b>21 22 23 24 25 26 27 28 29 30</b>

<b>31 32 33 34 35 36 37 38 39 40</b>

<b>Прерывание потока.</b>

<b>Прерывание потока отменено! Код завершения 0</b>

<b>41 42 43 44 45 46 47 48 49 50</b>

<b>51 52 53 54 55 56 57 58 59 60</b>

<b>61 62 63 64 65 66 67 68 69 70</b>

<b>71 72 73 74 75 76 77 78 79 80</b>

<b>Прерывание потока.</b>

<b>Поток прерван, код завершения 100</b>

<b>Основной поток прерван.</b>

Если в данном примере программы метод Abort() вызывается с нулевым аргументом, то запрос на преждевременное прерывание отменяется потоком, вызывающим метод ResetAbort(), и выполнение этого потока продолжается. Любое другое значение аргумента приведет к прерыванию потока.