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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 174 175 176 177 178 179 180 181 182 ... 407
(рис. 14.2).

Если тема потоков для вас нова, то не стоит беспокоиться о деталях. На данном этапе просто запомните, что любой поток представляет собой уникальный путь выполнения внутри процесса 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 *****

-> PID: 0       Name: Idle

-> PID: 4       Name: System

-> PID: 104     Name: Secure System

-> PID: 176     Name: Registry

-> PID: 908     Name: svchost

-> PID: 920     Name: smss

-> PID: 1016    Name: csrss

-> PID: 1020    Name: NVDisplay.Container

-> PID: 1104    Name: wininit

-> PID: 1112    Name: csrss

************************************

Исследование конкретного процесса

В дополнение к полному списку всех выполняющихся процессов на заданной машине статический метод Process.GetProcessById() позволяет получать одиночный объект Process по ассоциированному с ним идентификатору PID. В случае запроса несуществующего PID генерируется исключение ArgumentException. Например, чтобы получить объект Process, который представляет процесс с PID, равным 30592, можно написать следующий код:

// Если процесс с PID, равным 30592, не существует,

// то сгенерируется исключение во время выполнения.

static void GetSpecificProcess()

{

  Process theProc = null;

  try

  {

    theProc = Process.GetProcessById(30592);

  }

  catch(ArgumentException ex)

  {

    Console.WriteLine(ex.Message);

  }

}

К настоящему моменту вы уже знаете, как получить список всех процессов, а также специфический процесс на машине посредством поиска по PID. Наряду с выяснением идентификаторов PID и имен процессов класс Process позволяет просматривать набор текущих потоков и библиотек, применяемых внутри заданного процесса. Давайте посмотрим, как это делается.

Исследование набора потоков процесса

Набор потоков представлен в виде строго типизованной коллекции ProcessThreadCollection, которая содержит определенное количество отдельных объектов ProcessThread. В целях иллюстрации добавьте к текущему приложению приведенный далее вспомогательный статический метод:

static void EnumThreadsForPid(int pID)

{

  Process theProc = null;

  try

  {

    theProc = Process.GetProcessById(pID);

  }

  catch(ArgumentException ex)

  {

    Console.WriteLine(ex.Message);

    return;

  }

  // Вывести статистические сведения по каждому потоку

  // в указанном процессе.

  Console.WriteLine(

    "Here are the threads used by: {0}", theProc.ProcessName);

  ProcessThreadCollection theThreads = theProc.Threads;

  foreach(ProcessThread pt in theThreads)

  {

    string info =

       $"-> Thread ID: {pt.Id}tStart Time:

       {pt.StartTime.ToShortTimeString()}tPriority:

       {pt.PriorityLevel}";

    Console.WriteLine(info);

  }

  Console.WriteLine("************************************n");

}

Как видите, свойство Threads в типе System.Diagnostics.Process обеспечивает доступ к классу ProcessThreadCollection. Здесь для каждого потока внутри указанного клиентом процесса выводится назначенный идентификатор потока, время запуска и уровень приоритета. Обновите операторы верхнего уровня в своей программе, чтобы запрашивать у пользователя идентификатор PID процесса, подлежащего исследованию:

...

// Запросить у пользователя PID и вывести набор активных потоков.

Console.WriteLine("***** Enter PID of process to investigate *****");

Console.Write("PID: ");

string pID = Console.ReadLine();

int theProcID = int.Parse(pID);

EnumThreadsForPid(theProcID);

Console.ReadLine();

После запуска приложения можно вводить PID любого процесса на машине и просматривать имеющиеся внутри него потоки. В следующем выводе

1 ... 174 175 176 177 178 179 180 181 182 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

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