На некоторых машинах многопоточность по большей части является иллюзией, обеспечиваемой операционной системой. Машины с единственным (не поддерживающим гиперпотоки) центральным процессором не обладают возможностью обработки множества потоков в одно и то же время. Взамен один центральный процессор выполняет по одному потоку за единицу времени (называемую
Если тема потоков для вас нова, то не стоит беспокоиться о деталях. На данном этапе просто запомните, что любой поток представляет собой уникальный путь выполнения внутри процесса Windows. Каждый процесс имеет главный поток (созданный посредством точки входа исполняемого файла) и может содержать дополнительные потоки, которые создаются программно.
Взаимодействие с процессами используя платформу .NET Core
Несмотря на то что с процессами и потоками не связано ничего нового, способ взаимодействия с ними в рамках платформы .NET Core значительно изменился (в лучшую сторону). Чтобы подготовить почву для понимания области построения многопоточных сборок (см. главу 15), давайте начнем с выяснения способов взаимодействия с процессами, используя библиотеки базовых классов .NET Core.
В пространстве имен System.Diagnostics определено несколько типов, которые позволяют программно взаимодействовать с процессами и разнообразными типами, связанными с диагностикой, такими как журнал событий системы и счетчики производительности. В текущей главе нас интересуют только типы, связанные с процессами, которые описаны в табл. 14.1.
Класс System.Diagnostics.Process позволяет анализировать процессы, выполняющиеся на заданной машине (локальные или удаленные). В классе Process также определены члены, предназначенные для программного запуска и завершения процессов, просмотра (или модификации) уровня приоритета процесса и получения списка активных потоков и/или загруженных модулей внутри указанного процесса. В табл. 14.2 перечислены некоторые основные свойства класса System.Diagnostics.Process.
Кроме перечисленных выше свойств в классе System.Diagnostics.Process определено несколько полезных методов (табл. 14.3).
Перечисление выполняющихся процессов
Для иллюстрации способа манипулирования объектами Process создайте новый проект консольного приложения C# по имени ProcessManipulator и определите в классе Program следующий вспомогательный статический метод (не забудьте импортировать в файл кода пространства имен System.Diagnostics и System.Linq):
static void ListAllRunningProcesses()
{
// Получить все процессы на локальной машине, упорядоченные по PID.
var runningProcs =
from proc
in Process.GetProcesses(".")
orderby proc.Id
select proc;
// Вывести для каждого процесса идентификатор PID и имя.
foreach(var p in runningProcs)
{
string info = $"-> PID: {p.Id}\tName: {p.ProcessName}";
Console.WriteLine(info);
}
Console.WriteLine("************************************\n");
}
Статический метод Process.GetProcesses() возвращает массив объектов Process, которые представляют выполняющиеся процессы на целевой машине (передаваемая методу строка "." обозначает локальный компьютер). После получения массива объектов Process можно обращаться к любым членам, описанным в табл. 14.2 и 14.3. Здесь просто для каждого процесса выводятся идентификатор PID и имя с упорядочением по PID. Модифицируйте операторы верхнего уровня, как показано ниже:
using System;
using System.Diagnostics;
using System.Linq;
Console.WriteLine("***** Fun with Processes *****\n");
ListAllRunningProcesses();
Console.ReadLine();
Запустив приложение, вы увидите список имен и идентификаторов PID для всех процессов на локальной машине. Ниже показана часть вывода (ваш вывод наверняка будет отличаться):
***** Fun with Processes *****