Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры по C_1.docx
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
1.11 Mб
Скачать

Создание потока. Чтобы создать поток, необходимо создать объект типа Thread. В классе Thread определен следующий конструктор: public Thread(ThreadStart entryPoint),

тип ThreadStart — это делегат, определенный в среде .NET Framework: public delegate void ThreadStart().

Итак, начальный метод должен иметь тип возвращаемого значения void и не принимать никаких аргументов. Выполнение созданного потока не начнется до тех пор, пока не будет вызван метод Start(), который определяется в классе Thread. Его определение выглядит так: public void Start().

Начавшись, выполнение потока будет продолжаться до тех пор, пока не завершится метод, заданный параметром entryPoint. Поэтому после выхода из entryPoint-метода выполнение потока автоматически завершается. Если попытаться вызвать метод Start() для потока, запущенного на выполнение, будет сгенерировано исключение типа ThreadStateException. После создания потока заданный метод начинает в нем свою работу, а первичный поток продолжает выполняться.

Приоритет потоков. Класс Thead поддерживает установку и получение приоритета потока. Для этого используется перечисление ThreadPriority. Его значения:

Highest Наивысший приоритет

Above Normal Приоритет выше обычного (Normal)

Normal Приоритет по умолчанию

Below Normal Приоритет ниже обычного

Lowest Самый низкий приоритет

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

Часто в многопоточной программе нужно позаботиться о том, чтобы основной поток завершался последним. Формально программа продолжает выполняться до тех пор, пока не завершатся все высокоприоритетные потоки. Таким образом, совсем необязательно завершение основного потока последним. Однако добиваться этого — считается одним из признаков хорошего стиля программирования, поскольку в этом случае ясно определяется конечная точка программы.

  1. Использование нескольких потоков. Планирование потоков, приоритеты потоков. Можно создавать в программе несколько дочерних потоков.

Задание: Выполнить одну операцию в нескольких потоках.

Создать статический метод SimpleWork() в классе MultiThread (перед методом Main), который выводит на экран Id-номер каждого потока:

class MultiThread

{

static void SimpleWork()

{

Console.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId);

}

static void Main(string[] args)

{

ThreadStart operation = new ThreadStart(SimpleWork);

for (int x = 1; x <= 5; ++x)

{

// Создаем новый поток, но не запускаем его

Thread theThread = new Thread(operation);

// Запускаем задачу в новом потоке

theThread.Start();

}

Здесь заданная операция выполняется в пяти отдельных потоках. Синхронность работы этих потоков зависит от возможностей компьютера. После внесения этих изменений мы получим пять потоков, каждый из которых выводит в окне консоли собственный идентификатор:

Thread: 3 Thread: 4 Thread: 5 Thread: 6 Thread: 7

Номера потоков выводятся последовательно, так как выполняемая методом SimpleWork операция завершается очень быстро. Попробуем запрограммировать более сложную операцию, чтобы изучить синхронную работу потоков:

Задание: Замедлить работу потока, позволяя другим потокам продолжить выполнение.

static void SimpleWork()

{

for (int x = 1; x <= 10; ++x)

{

Console.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId);

Console.WriteLine("Номер итерации " + x);

Thread.Sleep(50);

}

}

// В Main():

for (int x = 1; x <= 3; ++x)

{

Thread theThread = new Thread(operation);

theThread.Start();

}

В методе SimpleWork мы выводим на экран идентификатор потока (их три) 10 раз. Кроме того, мы используем Thread.Sleep, чтобы замедлить работу кода. Метод Thread.Sleep позволяет приостановить выполнение потока на заданное время (в миллисекундах), тогда как остальные потоки будут продолжать работу. Работа каждого потока останавливается на 50 миллисекунд, и другие потоки в это время выводят свои данные на консоль. Чтобы посмотреть, как это работает, мы изменили метод SimpleWork так, чтобы он показывал номер текущей итерации:

Thread:3 Thread:4 Thread:5 Thread:6 Thread:7 Thread:3 Thread: 4Thread:5 Thread:6 Thread:7

Это позволило достичь максимально параллельного выполнения операций, возможного для компьютера с данной конфигурацией.