Чтение онлайн

на главную - закладки

Жанры

Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:

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

Делегаты, регистрация callback делегата в пуле рабочих потоков

В коде метода InitIfNecessary класса SynchronizationAttribute используются упомянутые в заголовке данного раздела сущности. Познакомимся с их применением в процессе разбора следующего примера:

using System;

using System.Threading;

public class Test {

private AutoResetEvent _myEvent;

private int _count = 0;

public Test {

Console.WriteLine("»> Test constructor thread = " +

Thread.CurrentThread.GetHashCode +

" IsPoolThread = " +

Thread.CurrentThread.IsThreadPoolThread);

_myEvent = new AutoResetEvent(false);

WaitOrTimerCallback myCallBackDelegate =

new WaitOrTimerCallback(this.MyCallBack);

ThreadPool.RegisterWaitForSingleObject

Х

_myEvent,

myCallBackDelegate,

null,

100,

false);

}

public int count {

get { return _count; }

set { _count = value;}

}

private delegate String MyDelegate ;

private void MyCallBack (Object state, bool timedOut) {

Console.WriteLine("»> MyCallback thread = " +

Thread.CurrentThread.GetHashCode +

" IsPoolThread = " +

Thread.CurrentThread.IsThreadPoolThread);

MyDelegate hello = new MyDelegate(MyHello);

count++;

Console.WriteLine(hello + " Count = " + count +

" timedOut = " + timedOut);

}

private String MyHello {

return "Test_" + count +": ";

}

public void NewEvent {

_myEvent.Set;

}

}

public class MyApp {

public static void Main {

Console.WriteLine("ЮЮ> MyApp thread = " +

Thread.CurrentThread.GetHashCode +

" IsPoolThread = " +

Thread.CurrentThread.IsThreadPoolThread);

Test test = new Test;

test.NewEvent;

Thread.Sleep(500);

test.NewEvent;

Thread.Sleep(1000);

}

}

Опишем прежде всего семантику нашего приложения.

Метод Main выполняется в основном потоке приложения. Все приложение в целом завершается по завершении этого метода (после возвращения из вызова функции Thread.Sleep (1000)). Параллельно с выполнением основного потока несколько раз успевает выполниться метод MyCallBack класса Test. Заметим, что этот метод выполняется так называемыми рабочими потоками, извлекаемыми системой из пула рабочих потоков. Рабочий поток не может пережить основной поток и по завершении последнего завершается и текущий рабочий поток.

Данное консольное приложение после запуска прежде всего выводит на консоль информацию о потоке, выполняющем код функции Main. Это хеш потока и информация о том, является ли данный поток рабочим потоком. Очевидно, что в данном случае значение последнего параметра должно быть равно false так как текущий поток является

основным потоком приложения.

Далее вызывается конструктор класса Test. Здесь также выводится информация о потоке — том потоке, который выполняет код конструктора. Этот тот же самый основной поток приложения.

Далее в конструкторе создается экземпляр myEvent события типа AutoResetEvent. События в .NET еще не обсуждались в данном курсе, но в данном случае используется событие специального типа, реализованное в системе. В связи с этим пока будет достаточно рассмотреть только это событие и только в контексте данного примера.

Для работы с пулом потоков мы регистрируем с помощью статического метода ThreadPool.RegisterWaitForSingleObject делегат myCallBackDelegate специального известного системе типа WaitOrTimerCallback. Делегат является некоторым аналогом указателя на функцию (в данном случае на MуCаllBаск), которая должна иметь сигнатуру, заданную при объявлении делегата. В случае делегата типа WaitOrTimerCallback возвращаемое значение должно отсутствовать (void), первый аргумент должен иметь тип System.Object и может использоваться для передачи вызываемой функции произвольных данных, второй параметр должен иметь тип bool и система через него передает значение true, если данный вызов произошел в связи с истечением времени ожидания (см. объяснение ниже).

Функция, ссылка на которую передана в делегат, будет вызываться и исполняться некоторым рабочим потоком из пула как только произойдет одно из двух событий:

• Событие _myEvent (зарегестрированное вместе с делегатом) будет установлено в состояние signaled

Для установки события типа AutoResetEvent в данное состояние достаточно вызвать его метод Set .

• Время ожидания превысило пороговое значение (четвертый параметр в ThreadPool.RegisterWaitForSingleObject)

Отсчет времени идет от момента регистрации делегата или от момента последнего его вызова.

Заметим, что при создании myEvent вызывался конструктор AutoResetEvent (false). Задание параметра false привело к созданию события, не находящегося в состоянии signaled. При задании в этом конструкторе параметра true инициированное событие сразу же находится в состоянии signaled, и делегат вызывается сразу же после его регистрации.

Событие AutoResetEvent обладает еще одним важным свойством, отраженным в его названии — оно переходит в исходное состояние автоматически после очередного вызова делегата.

Третий параметр в ThreadPool.RegisterwaitForSingleObject задает ссылку на объект, содержащий данные передаваемые связанной с делегатом функции при вызове последнего (в данном случае ничего не передается).

Последний параметр определяет, что делегат зарегистрирован навсегда (точнее в данном случае до момента уничтожения экземпляра класса Test, в конструкторе которого выполняется регистрация). Если бы последний параметр равнялся true, регистрация делегата была бы действительна только на один вызов.

Поделиться:
Популярные книги

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи

Глинглокский лев. (Трилогия)

Степной Аркадий
90. В одном томе
Фантастика:
фэнтези
9.18
рейтинг книги
Глинглокский лев. (Трилогия)

Хроники сыска (сборник)

Свечин Николай
3. Сыщик Его Величества
Детективы:
исторические детективы
8.85
рейтинг книги
Хроники сыска (сборник)

Болотник 3

Панченко Андрей Алексеевич
3. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 3

Альмар. Мой новый мир. Дилогия

Ищенко Геннадий Владимирович
Альмир
Фантастика:
фэнтези
попаданцы
8.09
рейтинг книги
Альмар. Мой новый мир. Дилогия

Пустоцвет

Зика Натаэль
Любовные романы:
современные любовные романы
7.73
рейтинг книги
Пустоцвет

А небо по-прежнему голубое

Кэрри Блэк
Фантастика:
фэнтези
5.00
рейтинг книги
А небо по-прежнему голубое

Попаданка в Измену или замуж за дракона

Жарова Анита
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Попаданка в Измену или замуж за дракона

Развод, который ты запомнишь

Рид Тала
1. Развод
Любовные романы:
остросюжетные любовные романы
короткие любовные романы
5.00
рейтинг книги
Развод, который ты запомнишь

Часовая башня

Щерба Наталья Васильевна
3. Часодеи
Фантастика:
фэнтези
9.43
рейтинг книги
Часовая башня

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Идеальный мир для Лекаря 17

Сапфир Олег
17. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 17

Тайный наследник для миллиардера

Тоцка Тала
Любовные романы:
современные любовные романы
5.20
рейтинг книги
Тайный наследник для миллиардера