Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 277 278 279 280 281 282 283 284 285 ... 642

{

  Lowest,

  BelowNormal,

  Normal,       // Стандартное значение.

  AboveNormal,

  Highest

}

В случае присваивания уровню приоритета потока значения, отличающегося от стандартного(ThreadPriority.Normal), помните об отсутствии прямого контроля над тем, когда планировщик потоков будет переключать потоки между собой. Уровень приоритета потока предоставляет среде .NET Core Runtime лишь подсказку относительно важности действия потока. Таким образом, поток с уровнем приоритета ThreadPriority.Highest не обязательно гарантированно получит наивысший приоритет.

Опять-таки, если планировщик потоков занят решением определенной задачи (например, синхронизацией объекта, переключением потоков либо их перемещением), то уровень приоритета, скорее всего, будет соответствующим образом изменен. Однако при прочих равных условиях среда .NET Core Runtime прочитает эти значения и проинструктирует планировщик потоков о том, как лучше выделять кванты времени. Потоки с идентичными уровнями приоритета должны получать одинаковое количество времени на выполнение своей работы.

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

Ручное создание вторичных потоков

Когда вы хотите программно создать дополнительные потоки для выполнения какой-то единицы работы, то во время применения типов из пространства имен System.Threading следуйте представленному ниже предсказуемому процессу.

1. Создать метод, который будет служить точкой входа для нового потока.

2. Создать новый делегат ParametrizedThreadStart (или ThreadStart), передав его конструктору адрес метода, который был определен на шаге 1.

3. Создать объект Thread, передав конструктору в качестве аргумента делегат ParametrizedThreadStart/Threadstart.

4. Установить начальные характеристики потока (имя, приоритет и т.д.).

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

Согласно шагу 2 для указания на метод, который будет выполняться во вторичном потоке, можно использовать два разных типа делегата. Делегат ThreadStart способен указывать на любой метод, который не принимает аргументов и ничего не возвращает. Такой делегат может быть полезен, когда метод предназначен просто для запуска в фоновом режиме без дальнейшего взаимодействия с ним.

Ограничение ThreadStart связано с невозможностью передавать ему параметры для обработки. Тем не менее, тип делегата ParametrizedThreadStart позволяет передать единственный параметр типа System.Object. Учитывая, что с помощью System.Object представляется все, что угодно, посредством специального класса или структуры можно передавать любое количество параметров. Однако имейте в виду, что делегаты ThreadStart и ParametrizedThreadStart могут указывать только на методы, возвращающие void.

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

Работа с делегатом ThreadStart

Чтобы проиллюстрировать процесс построения многопоточного приложения (а также его полезность), создайте проект консольного приложения по имени SimpleMultiThreadApp, которое позволит конечному пользователю выбирать, будет приложение выполнять свою работу в единственном первичном потоке или же разделит рабочую нагрузку с применением двух отдельных потоков выполнения.

После импортирования пространства имен System.Threading определите метод для выполнения работы (возможного) вторичного потока. Чтобы сосредоточиться на механизме построения многопоточных программ, этот метод будет просто выводить на консоль последовательность чисел, делая на каждом шаге паузу примерно в 2 секунды. Ниже показано полное определение класса Printer:

using System;

using System.Threading;

namespace SimpleMultiThreadApp

{

  public class Printer

  {

    public void PrintNumbers()

  {

      // Вывести информацию о потоке.

      Console.WriteLine("-> {0} is executing PrintNumbers()",

        Thread.CurrentThread.Name);

      // Вывести числа.

      Console.Write("Your numbers: ");

      for(int i = 0; i < 10; i++)

      {

        Console.Write("{0}, ", i);

        Thread.Sleep(2000);

      }

      Console.WriteLine();

    }

  }

}

Добавьте в файл Program.cs операторы верхнего уровня, которые предложат пользователю решить, сколько потоков будет использоваться для выполнения работы приложения: один или два. Если пользователь запрашивает один поток, то нужно просто вызвать метод PrintNumbers() в первичном потоке. Тем не менее, когда пользователь выбирает два потока, понадобится создать делегат ThreadStart, указывающий на PrintNumbers(), передать объект делегата конструктору нового объекта Thread и вызвать метод Start() для информирования среды .NET Core Runtime о том, что данный поток готов к обработке. Вот полная реализация:

using System;

using System.Threading;

using SimpleMultiThreadApp;

1 ... 277 278 279 280 281 282 283 284 285 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий