вторник, 12 октября 2010 г.

Использование OmniThread Libray (OTL) для создания многопоточных приложений - 14

Внутренняя организация OTL

Что бы успешно двигаться дальше, давайте немного углубимся в дебри OTL и поговорим о внутреннем устройстве данной библиотеки.
Самый важный модуль  OTL OtlTaskControl.pas. Это модуль с помощью интерфейса устанавливает связь с потоковой задачей.

Самый важный интерфейс в OTL - IOmniTaskControl. Это интерфейс служит для управления фоновой задачей. Данный интерфейс получается из функции CreateTask. Интерфейс используется для управления задачей, а также для средств связи между задачами (фоновыми потоками) и основной программой (основным потоком программы).
Существует три способа вызова CreateTask (есть еще и четвертый способ, но он доступен начиная с версии Delphi 2009 и будет разобран подробнее в разделе “Создание задачи”). Наши же три способа соответствуют трем перегруженным методам CreateTask. Каждый метод обращается к своему конструктору. Конструкторы в свою очередь задают параметры выполнения данной фоновой задачи и инициализируют некоторые события, используемые для управления задачи.
IOmniTaskControl Способы вызовов CreateTask
function CreateTask(worker: TOmniTaskProcedure; const taskName: string = ''): 
         IOmniTaskControl; overload;
function CreateTask(worker: TOmniTaskMethod; const taskName: string = ''):
         IOmniTaskControl; overload;
function CreateTask(const worker: IOmniWorker; const taskName: string = ''):
         IOmniTaskControl; overload;

Помимо CreateTask в OtlTaskControl есть метод SetParameter, который используется OTL, для передачи пользовательских параметров (заданных программистом), фоновой задаче. Данные методы можно использовать для предварительной инициализации данных, задаваемых программистом для решения конкретной задачи. То есть в фоновую задачу c помощью методов  SetParameter  можно передавать различные начальные значения переменных, констант и прочие данные, которые будут обработаны в методе фоновой задачи.
IOmniTaskControl Способы вызовов SetParameter
function  SetParameter(const paramName: string; const paramValue: TOmniValue):
                       IOmniTaskControl; overload;
function  SetParameter(const paramValue: TOmniValue): IOmniTaskControl; overload;
function  SetParameters(const parameters: array of TOmniValue): IOmniTaskControl;

Следующие четыре метода используются, для управления внутренним поведением цикла событий/сообщений. Они работают только с объектами реализующими интерфейс IOmniWorker или классами-потомками TOmniWorker.
IOmniTaskControl Управление внутренним циклом событий/сообщений
function  Alertable: IOmniTaskControl;
function  FreeOnTerminate: IOmniTaskControl;
function  MsgWait(wakeMask: DWORD = QS_ALLEVENTS): IOmniTaskControl;
function  Settimer(interval_ms: cardinal; timerMessage: integer = -1): IOmniTaskControl;

Методы Alertable и MsgWait заставляют внутренний цикл сообщений OTL ждать сообщения, для того, что бы после передать их  на обработку.
Метод  SetTimer заставляет сообщение с идентификатором timerMessage  быть отправленными рабочей задаче в указанных временных интервалах. Если параметр функции SetTimer будет равен -1, то вместо этого метода будет вызван метод Timer.
Метод FreeOnTerminate доступен, когда существует рабочая задача (фоновый поток) класса TOmniWorker. Метод заставляет фоновую задачу быть автоматически уничтоженной после окончания работы.
IOmniTaskControl Управление мониторингом
function  RemoveMonitor: IOmniTaskControl;
function  SetMonitor(hWindow: THandle): IOmniTaskControl;

Метод SetMonitor используется, для того чтобы обеспечить мониторинг работы фоновой задачи и задействовать функции связи между фоновым потоком и программой. Типичное использование метода SetMonitor вместе с компонентом TOmniEventMonitor. Соответственно TOmniEventMonitor поддерживающий интерфейс IOmniTaskControlMonitor будет иметь методы - Monitor и Detach. Метод RemoveMonitor открепляет задачу от мониторинга.
IOmniTaskControl Запуск фоновой задачи (потока)
function  Run: IOmniTaskControl;
function  Schedule(const threadPool: IOmniThreadPool = nil {default pool}):
                                                                    IOmniTaskControl;

Чтобы запустить задачу, Вы должны вызвать метод Run или метод Schedule (запуск потока в пуле задач IOmniThreadPool).
IOmniTaskControl Управление
function  Terminate(maxWait_ms: cardinal = INFINITE): boolean;
function  TerminateWhen(event: THandle): IOmniTaskControl;
function  WaitFor(maxWait_ms: cardinal): boolean;
function  WaitForInit: boolean;

Данные методы управляют задачей. Метод Terminate ждет корректного завершения задачи в заданный период времени. В настоящее время метод возвращает False, если задача не заканчивается в выделенное время. В будущем автор, возможно, изменит поведение данного метода, внеся гарантированное уничтожение задачи (потока) по истечению времени.
Метод TerminateWhen используется с  объектом IOmniCancellationToken в пуле потоков. Идея метода в том, что бы использовать одно событие  для остановки множества задач сразу.
Метод WaitFor ждет окончание задачи и возвращает True, если задача завершена.
Метод WaitForInit (ждать инициализацию) ждет выполнение метода Initialize рабочей (выполняющейся) задачи IOmniWorker/TOmniWorker. Метод возвращает значение  переданное методом Initialize.
IOmniTaskControl
property Comm: IOmniCommunicationEndpoint read GetComm;
property ExitCode: integer read GetExitCode;
property ExitMessage: string read GetExitMessage;
property Name: string read GetName;
property Options: TOmniTaskControlOptions read otcOptions write otcOptions;
property UniqueID: cardinal read GetUniqueID;

Свойство Comm предоставляет доступ к подсистеме связи. Практические навыки его использования мы его уже частично рассмотрели на примерах ранее. Более подробно систему связи мы рассмотрим далее.
Свойства ExitCode и ExitMessage возвратят код завершения задачи и сообщение. Если во время работы задачи произойдет исключение, то код исключение и сообщение об ошибке будут переданы через эти свойства.
Свойство Name возвращает имя задачи, как оно было установлено в конструкторе CreateTasks, и UniqueID возвращает идентификатор задачи. Этот идентификатор уникален в приложении.
Свойство Options дает вам  прямой доступ к опциям выполнения задачи, обычно устанавливаемым с Alertable, MsgWait, и FreeOnTerminate.

Комментариев нет:

Отправить комментарий