Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Межпроцессорное взаимодействие и многопоточность в .NET (реферат).docx
Скачиваний:
30
Добавлен:
28.06.2014
Размер:
139.35 Кб
Скачать

ManualResetEvent – составляющие Методы

  • Close

При переопределении в производном классе освобождает все ресурсы, занимаемые текущим объектом WaitHandle.

  • Reset

Задает несигнальное состояние указанного события.

  • Set

Задает сигнальное состояние указанного события.

  • WaitOne

Блокирует текущий поток до получения сигнала текущим объектом WaitHandle.

Определение:

public virtual void Close();

public bool Reset();

public bool Set();

public virtual bool WaitOne();

Примеры

  1. Пример использования классов AutoResetEvent и ManualResetEvent. Их отличие состоит в том, что для класса ManualResetEvent после подачи им сигнала нужно вручную сбрасывать его состояние в false (то есть вызывать метод Reset), для AutoResetEvent это происходит автоматически (как только сработал один из статических методов WaitAny, WaitAll или WaitOne). Это демонстрируется в ниже – приведенном примере (более глубоко изучить данную тему можно в [8])

using System;

using System.Threading;

class CalculateTest

{

static void Main()

{

//Объект вычислений

Calculate calc = new Calculate();

//Вывод результатов вычислений

Console.WriteLine("Result = {0}.",

calc.Result(234).ToString());

Console.WriteLine("Result = {0}.",

calc.Result(55).ToString());

Console.Read();

}

}

class Calculate

{

double baseNumber, firstTerm, secondTerm, thirdTerm;

AutoResetEvent[] autoEvents;

ManualResetEvent manualEvent;

// Генерация случайных чисел для имитации вычислений

Random randomGenerator;

//Конструктор (инициализация объектов AutoResetEvent

//и ManualResetEvent)

public Calculate()

{

autoEvents = new AutoResetEvent[]

{

new AutoResetEvent(false),

new AutoResetEvent(false),

new AutoResetEvent(false)

};

manualEvent = new ManualResetEvent(false);

}

void CalculateBase(object stateInfo)

{

//Эмитация вычислений

baseNumber = randomGenerator.NextDouble();

// Сигнал о том что baseNumber подсчитан

manualEvent.Set();

}

//Следующие три метода аналогичны по своей сути

void CalculateFirstTerm(object stateInfo)

{

// Вычисляем preCalc

double preCalc = randomGenerator.NextDouble();

// Ожидаем вычисления baseNumber

manualEvent.WaitOne();

// Вычисляем первый терм(нужны preCalc и baseNumber).

firstTerm = preCalc * baseNumber *

randomGenerator.NextDouble();

// Сигнал о том что первый терм вычислен

autoEvents[0].Set();

}

void CalculateSecondTerm(object stateInfo)

{

double preCalc = randomGenerator.NextDouble();

manualEvent.WaitOne();

secondTerm = preCalc * baseNumber *

randomGenerator.NextDouble();

autoEvents[1].Set();

}

void CalculateThirdTerm(object stateInfo)

{

double preCalc = randomGenerator.NextDouble();

manualEvent.WaitOne();

thirdTerm = preCalc * baseNumber *

randomGenerator.NextDouble();

autoEvents[2].Set();

}

public double Result(int seed)

{

randomGenerator = new Random(seed);

// Одновременное вычисления термов

// Запускаем соответствующие методы(все

// метожы запускаються в фоновых потоках)

ThreadPool.QueueUserWorkItem(

new WaitCallback(CalculateBase));

ThreadPool.QueueUserWorkItem(

new WaitCallback(CalculateFirstTerm));

ThreadPool.QueueUserWorkItem(

new WaitCallback(CalculateSecondTerm));

ThreadPool.QueueUserWorkItem(

new WaitCallback(CalculateThirdTerm));

// Ожидаем вычисления всех трех термов

// (всех трех сигналов от autoEvents)

WaitHandle.WaitAll(autoEvents);

// Сбрасываем сигнал manualEvent на false

// для следующего вычисления тройки термов

// (сигналы autoEvents сбрасываються автоматически)

manualEvent.Reset();

return firstTerm + secondTerm + thirdTerm;

}

}

Выходная информация:

Result = 0,64236347437457457

Result = 0,25234563246456456