Прежде чем погрузиться в детали пространства имен
System.Threading
, библиотеки TPL и ключевых слов
async
и
await
языка С#, мы начнем с выяснения того, каким образом можно применять тип делегата .NET Core для вызова метода в асинхронной манере. Хотя вполне справедливо утверждать, что с выходом версии .NET 4.6 ключевые слова
async
и
await
предлагают более простую альтернативу асинхронным делегатам, по-прежнему важно знать способы взаимодействия с кодом, использующим этот подход (в производственной среде имеется масса кода, в котором применяются асинхронные делегаты).
Пространство имен System.Threading
В рамках платформ .NET и .NET Core пространство имен
System.Threading
предоставляет типы, которые дают возможность напрямую конструировать многопоточные приложения. В дополнение к типам, позволяющим взаимодействовать с потоком .NET Core Runtime, в
System.Threading
определены типы, которые открывают доступ к пулу потоков, обслуживаемому .NET Core Runtime, простому (не связанному с графическим пользовательским интерфейсом) классу
Timer
и многочисленным типам, применяемым для синхронизированного доступа к разделяемым ресурсам.
В табл. 15.1 перечислены некоторые важные члены пространства имен
System.Threading
. (За полными сведениями обращайтесь в документацию по .NET Core.)
Класс System.Threading.Thread
Класс
Thread
является самым элементарным из всех типов в пространстве имен
System.Threading
. Он представляет объектно-ориентированную оболочку вокруг заданного пути выполнения внутри отдельного домена приложения. В этом классе определено несколько методов (статических и уровня экземпляра), которые позволяют создавать новые потоки внутри текущего домена приложения, а также приостанавливать, останавливать и уничтожать указанный поток. Список основных статических членов приведен в табл. 15.2.
Класс
Thread
также поддерживает члены уровня экземпляра, часть которых описана в табл. 15.3.
На заметку! Прекращение работы или приостановка активного потока обычно считается плохой идеей. В таком случае есть шанс (хотя и небольшой), что поток может допустить "утечку" своей рабочей нагрузки.
Получение статистических данных о текущем потоке выполнения
Вспомните, что точка входа исполняемой сборки (т.е. операторы верхнего уровня или метод
Main()
) запускается в первичном потоке выполнения. Чтобы проиллюстрировать базовое применение типа
Thread
, предположим, что имеется новый проект консольного приложения по имени
ThreadStats
. Как вам известно, статическое свойство
Thread.CurrentThread
извлекает объект
Thread
, который представляет поток, выполняющийся в текущий момент. Получив текущий поток, можно вывести разнообразные статистические сведения о нем:
// Не забудьте импортировать пространство имен System.Threading.
using System;
using System.Threading;
Console.WriteLine("***** Primary Thread stats *****\n");
// Получить имя текущего потока.
Thread primaryThread = Thread.CurrentThread;
primaryThread.Name = "ThePrimaryThread";
// Вывести статистические данные о текущем потоке.
Console.WriteLine("ID of current thread: {0}",
primaryThread.ManagedThreadId); // Идентификатор текущего потока
Console.WriteLine("Thread Name: {0}",
primaryThread.Name); // Имя потока
Console.WriteLine("Has thread started?: {0}",
primaryThread.IsAlive); // Запущен ли поток
Console.WriteLine("Priority Level: {0}",
primaryThread.Priority); // Приоритет потока
Console.WriteLine("Thread State: {0}",
primaryThread.ThreadState); // Состояние потока
Console.ReadLine();
Вот как выглядит вывод:
***** Primary Thread stats *****
ID of current thread: 1
Thread Name: ThePrimaryThread
Has thread started?: True
Priority Level: Normal
Thread State: Running
Свойство Name
Обратите внимание, что класс
Thread
поддерживает свойство по имени
Name
. Если значение
Name
не было установлено, тогда будет возвращаться пустая строка. Однако назначение конкретному объекту
Thread
дружественного имени может значительно упростить отладку. Во время сеанса отладки в Visual Studio можно открыть окно
Threads (Потоки), выбрав пункт меню
Debug►
Windows►
Threads (Отладка► Окна►Потоки). На рис. 15.1 легко заметить, что окно
Threads позволяет быстро идентифицировать поток, который нужно диагностировать.
Свойство Priority
Далее обратите внимание, что в типе
Thread
определено свойство по имени
Priority
. По умолчанию все потоки имеют уровень приоритета
Normal
. Тем не менее, в любой момент жизненного цикла потока его можно изменить, используя свойство
Priority
и связанное с ним перечисление
System.Threading.ThreadPriority
:
public enum ThreadPriority