Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прога - ответы2.docx
Скачиваний:
19
Добавлен:
23.04.2019
Размер:
206.38 Кб
Скачать

Создание вторичных потоков при помощи Thread.Start()

При программном создании дополнительных потоков для выполнения некоторой единицы работы необходимо следовать строго регламентированному процессу.

  1. Создать метод, который будет точкой входа для нового потока.

  2. Создать новый делегат ParametrizedThreadStart (или ThreadStart), передав конструктору адрес метода, определенного на шаге 1.

  3. Создать объект Thread, передав в качестве аргумента конструктора ParametrizedThreadStart/ThreadStart.

  4. Установить начальные характеристики потока (имя, приоритет и т.п.).

  5. Вызвать метод Thread.Start(). Это запустит поток на методе, который указан делегатом, созданным на шаге 2, как только это будет возможно.

Пример:

// класс для передачи параметров

class Params

{

public int a, b;

public Params(int a, int b)

{

this.a = a;

this.b = b;

}

}

// Тестовый класс

class Test

{

// метод, который будт выполняться в отдельном потоке (шаг 1)

static void Add(object data)

{

if ( data is Params )

{

AddParams ap = (AddParams)data;

// используем параметры

}

}

static void Launch()

{

// Создать объект Params для передачи вторичному потоку

Params p = new Params(10, 10);

// Создать делегат и объект Thread (шаги 2, 3)

Thread t = new Thread(new ParameterizedThreadStart(Add));

// Запустить поток (шаг 5) и передать ему параметр

t.Start(p);

}

}

Запуск потока с использованием ThreadStart практически не отличается от запуска потока через ParametrizedThreadStart, за исключением того, что методы для ThreadStart не должны принимать никаких параметров.

Синхронизация с помощью lock

// Маркер блокировки.

private object threadLock = new object();

public void function()

{

// Использование маркера блокировки,

lock ( threadLock )

{

// Весь код внутри этого контекста безопасен к потокам.

}

}

Синхронизация с использованием типа System.Threading.Monitor

Фактически, компилятор преобразует предыдущий пример в код вида

// Маркер блокировки.

private object threadLock = new object();

public void Function()

{

// Использование блокировки

Monitor.Enter(threadLock);

try

{

// Весь код внутри этого контекста безопасен к потокам.

}

finally

{

// снять блокировку

Monitor.Exit(threadLock);

}

}

Синхронизация с использованием типа System.Threading.Interlocked

System.Threading.Interlocked предоставляет функциональность для потокобезопасного манипулирования одним элементом данных, например:

Decrement()

Безопасно уменьшает значение параметра на 1

Exchange()

Безопасно меняет значения двух параметров местами

Increment()

Безопасно уменьшает значение параметра на 1

Синхронизация с использованием атрибута [Synchronization]

Для обеспечения потокобезопасной работы целого класса, он помечается атрибутом [Synchronization]. Класс должен наследовать от ContextBoundObject . Данный подход требует аккуратного использования, поскольку синхронизации подвергаются все члены отмеченного класса, вне зависимости от того, действительно ли это нужно, что может замедлить работу программы.