Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Примечание






Хотя формальное описание Execute — метод abstract, но мастер создания нового объекта TThread создает пустой шаблон этого метода.

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

Если поток был создан с аргументом

CreateSuspended: = False, то метод Execute выполняется немедленно,

в противном случае Execute выполняется после вызова метода Resume.

Если поток рассчитан на однократное выполнение каких-либо действий, то никакого специального кода завершения внутри Execute писать не надо.

Если же в потоке будет выполняться какой-то цикл, и поток должен завершиться вместе с приложением, то условия окончания цикла должны быть примерно такими:

procedure TMyThread.Execute;

begin

Repeat

DoSomething;

Until CancelCondition or Terminated;

end;

Здесь CancelCondition — ваше личное условие завершения потока (исчерпание данных, окончание вычислений, поступление на вход того или иного символа и т. д.),

а свойство Terminated сообщает о завершении потока (это свойство может быть установлено как изнутри потока, так и извне; чаще всего, завершается породивший его процесс).

Конструктор объекта:

constructor Create (CreateSuspended: Boolean);

получает параметр CreateSuspended. Если его значение равно True, вновь созданный поток не начинает выполняться до тех пор, пока не будет сделан вызов метода Resume.

В случае если параметр CreateSuspended имеет значение False, конструктор завершается и только затем поток начинает исполнение.

destructor Destroy; override;

Деструктор Destroy вызывается, когда необходимость в созданном потоке отпадает. Деструктор завершает его и высвобождает все ресурсы, связанные с объектом TThread.

function Terminate: Integer;

Для окончательного завершения потока (без последующего запуска) существует метод Terminate. Этот метод не делает никаких принудительных действий по остановке потока. Все, что происходит, — это установка свойства

property Terminated: Boolean;

в значение True. Таким образом, Terminate — это указание потоку завершиться, выраженное " в мягкой форме", с возможностью корректно освободить ресурсы. Если нужно немедленно завершить поток, лучше использовать функцию Windows API TerminateThread.

Примечание

Метод Terminate автоматически вызывается и из деструктора объекта. Поток — объект VCL будет дожидаться, пока завершится поток — объект операционной системы. Таким образом, если поток не умеет завершаться корректно, вызов деструктора потенциально может привести к зависанию всей программы.

Еще одно полезное свойство:

property FreeOnTerminate: Boolean;

Если это свойство равно True, то деструктор потока будет вызван автоматически по его завершении. Это очень удобно для тех случаев, когда нет уверенности в том, когда именно завершится поток, и необходимо использовать его по принципу " выстрелил и забыл" (fire and forget).

function WaitFor: Integer;

Метод WaitFor предназначен для синхронизации и позволяет одному потоку дождаться момента, когда завершится другой поток. Если вы внутри потока FirstThread пишите код

Code: = SecondThread.WaitFor;

то это означает, что поток FirstThread останавливается до момента завершения потока SecondThread. Метод WaitFor возвращает код завершения ожидаемого потока (см. свойство Returnvalue).

property Handle: THandle read FHandle;

property ThreadID: THandle read FThreadID;

Свойства Handle и ThreadID дают программисту непосредственный доступ к потоку средствами API Win32. Если разработчик хочет обратиться к потоку и управлять им, минуя возможности класса TThread, значения Handle и ThreadID могут быть использованы в качестве аргументов функций API Win32.

Например, если программист хочет перед продолжением выполнения приложения дождаться завершения сразу нескольких потоков, он должен вызвать функцию API WaitForMultipieObjects; для ее вызова необходим массив дескрипторов потоков.

property Priority: TThreadPriority;

Свойство Priority позволяет запросить и установить приоритет потоков. Допустимыми значениями приоритета для объектов TThread являются tpIdle, tpLowest, tpLower, tpNormai, tpHigher, tpHighest и tpTimeCritical.

procedure Synchronize (Method: TThreadMethod);

Этот метод относится к секции protected, т. е. может быть вызван только из потомков TThread.

Delphi предоставляет программисту метод Synchronize для безопасного вызова методов VCL внутри потоков.

Во избежание конфликтных ситуаций, метод Synchronize дает гарантию, что к каждому объекту VCL одновременно имеет доступ только один поток.

Аргумент, передаваемый в метод Synchronize, — это имя метода, который производит обращение к VCL; вызов Synchronize с этим параметром — это тоже, что и вызов самого метода. Такой метод (класса TThreadMethod) не должен иметь никаких параметров и не должен возвращать никаких значений. К примеру, в основной форме приложения нужно предусмотреть функцию

procedure TMainForm.SyncShowMessage;

begin

ShowMessage (IntToStr (ThreadList1.Count)); // другие обращения к VCL

end;

а в потоке для показа сообщения писать не

ShowMessage (IntToStr(ThreadListl.Count));

и даже не

MainForm.SyncShowMessage;

а только так:

Synchronize (MainForm.SyncShowMessage);

Примечание

Производя любое обращение к объекту VCL из потока, убедитесь, что при этом используется метод Synchronize; в противном случае результаты могут оказаться непредсказуемыми. Это верно даже в том случае, если вы используете средства синхронизации, описанные ниже.

procedure Resume;

Метод Resume класса TThread вызывается, когда поток возобновляет выполнение после остановки, или для явного запуска потока, созданного с параметром CreateSuspended, равным True.

procedure Suspend;

Вызов метода Suspend приостанавливает поток с возможностью повторного запуска впоследствии. Метод Suspend приостанавливает поток вне зависимости от кода, исполняемого потоком в данный момент; выполнение продолжается с точки останова.

property Suspended: Boolean;

Свойство Suspended позволяет программисту определить, не приостановлен ли поток. С помощью этого свойства можно также запускать и останавливать поток.

Установив свойство Suspended в значение True, вы получите тот же результат, что и при вызове метода Suspend — приостановку. Наоборот, установка свойства Suspended в значение False возобновляет выполнение потока, как и вызов метода Resume.

property ReturnValue: Integer;

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

 

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

Для ее создания сначала на форму поместим панель TPanel, очистим ее свойство Caption.

Свойству Align присвоим значение аlRight.

Эта панель предназначена для размещения редактора TSpinEdit, кнопки TButton и индикатора TGauge и всегда должна располагаться в правой части окна программы (компоненты TSpinEdit и TGauge находятся на странице Samples палитры компонентов).

 

 

Установим в свойство SpinEditl.Value начение 2,

присвоим свойству Gauge1.Kind значение gkPie,

Gauge1.BorderStyle – bsNone

и Button1.Caption — 'Квадрат'.

На свободное место формы положим компонент TMemo и установим для него в свойство Align значение alLeft, а свойство Name - 'mmOutput'.

Создадим обработчик события Button1.Click: при нажатии на кнопку вначале содержимое редактора SpinEdit1 возводится в квадрат до тех пор, пока отображаемое в нем значение не слишком велико (больше 10 Е+1233).

В этот момент надпись на кнопке меняется на “корень”, а нажатие на нее вычисляет корень квадратный из величины SpinEdit1.

procedure TForm1.Button1Click(Sender: TObject);

Begin

if Tag=0 then

Begin

SpinEdit1.Text: = FloatToStr (sqr (StrToFloat (SpinEditl.Text)));

if StrToFloat(SpinEditl.Text) > 1e1233 then

Begin

Tag: = 1;

Button1.Caption: = 'Корень'

End

End

Else

Begin

SpinEdit1.Text: = FloatToStr(sqrt(StrToFloat(SpinEditl.Text)));






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.