Класс Thread

77

Класс Thread является самым элементарным из всех типов пространства имен System.Threading. Этот класс представляет объектно-ориентированную оболочку вокруг заданного пути выполнения внутри определенного AppDomain. Этот тип также определяет набор методов (как статических, так и уровня экземпляра), которые позволяют создавать новые потоки внутри текущего AppDomain, а также приостанавливать, останавливать и уничтожать определенный поток. Список основных статических членов приведен ниже:

CurrentContext

Это свойство только для чтения возвращает контекст, в котором в данный момент выполняется поток

CurrentThread

Это свойство только для чтения возвращает ссылку на текущий выполняемый поток

GetDomain(), GetDomainID()

Этот метод возвращает ссылку на текущий AppDomain или идентификатор этого домена, в котором выполняется текущии поток

Sleep()

Этот метод приостанавливает текущий поток на заданное время

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

Член уровня экземпляра Назначение
IsAlive Возвращает булевское значение, указывающее на то, запущен ли поток (и еще не прерван и не отменен)
IsBackground Получает или устанавливает значение, указывающее, является ли данный поток "фоновым" (подробнее объясняется далее)
Name Позволяет вам установить дружественное текстовое имя потока
Priority Получает или устанавливает приоритет потока, который может принимать значение из перечисления ThreadPriority
ThreadState Получает состояние данного потока, которому может быть присвоено значение из перечисления ThreadState
Abort() Инструктирует CLR прервать поток, как только это будет возможно
Interrupt() Прерывает (т.е. приостанавливает) текущий поток на заданный период ожидания
Join() Блокирует вызывающий поток до тех пор, пока указанный поток (тот, в котором вызван Join()) не завершится
Resume() Возобновляет ранее приостановленный поток
Start() Инструктирует CLR запустить поток как можно скорее
Suspend() Приостанавливает поток. Если поток уже приостановлен, вызов Suspend() не дает эффекта

Получение статистики о текущем потоке

Вспомните, что точка входа исполняемой сборки (т.е. метод Main()) запускается в первичном потоке выполнения. Чтобы проиллюстрировать базовое применение типа Thread, предположим, что имеется новое консольное приложение. Как известно, статическое свойство Thread.CurrentThread извлекает объект Thread, представляющий текущий выполняющийся поток. После получения текущего потока можно вывести разнообразную статистику о нем:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            Console.Title = "Информация о главном потоке программы";

            Thread thread = Thread.CurrentThread;
            thread.Name = "MyThread";
            Console.WriteLine(@"Имя домена приложения: {0}
ID контекста: {1}
Имя потока: {2}
Запущен ли поток? {3}
Приоритет потока: {4}
Состояние потока: {5}", 
Thread.GetDomain().FriendlyName, Thread.CurrentContext.ContextID, thread.Name, thread.IsAlive, thread.Priority, thread.ThreadState);
            Console.ReadLine();
        }
    }
}
Информация о потоке

Хотя этот код более-менее очевиден, обратите внимание, что класс Thread поддерживает свойство по имени Name. Если не установить его значение явно, то Name вернет пустую строку. Присваивание дружественного имени конкретному объекту Thread может значительно упростить отладку. Во время сеанса отладки в Visual Studio 2010 можно открыть окно Threads (Потоки), выбрав пункт меню Debug --> Windows --> Threads (Отладка --> Окна --> Потоки).

Обратите внимание, что в типе Thread определено свойство по имени Priority. По умолчанию все потоки имеют уровень приоритета Normal. Однако это можно изменить в любой момент жизненного цикла потока, используя свойство Thread.Priority и связанное с ним перечисление System.Threading.ThreadPriority:

public enum ThreadPriority
{
   Lowest,
   BelowNormal,
   Normal,	// Значение по умолчанию.
   AboveNormal,
   Highest
}

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

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

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

Пройди тесты
Лучший чат для C# программистов