При программном создании дополнительных потоков для выполнения некоторой единицы работы необходимо следовать строго регламентированному процессу.
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);
}
}