Читайте также: |
|
{$R *.dfm}
//Нужно создать процедуру Execute, уже описанную в классе TMyThread
procedure TMyThread.Execute;
begin
//Здесь описывается код, который будет выполняться в потоке
end;
Если поток создаётся мастером, т.е. в другом модуле, то не забудьте в основном модуле описать переменную - экземпляр потока, как указано выше. Также, поскольку класс потока описан в другом модуле, имя этого модуля необходимо добавить в секцию uses. Теперь можно запускать поток, даже если в его процедуре Execute нет ни единого оператора.
//Запускать поток будем нажатием на кнопку:
procedure TForm1.Button1Click(Sender: TObject);
begin
//Вначале нужно создать экземпляр потока:
MyThread:=TMyThread.Create(False);
//Параметр False запускает поток сразу после создания, True - запуск впоследствии, методом Resume
//Далее можно указать параметры потока, например приоритет:
MyThread.Priority:=tpNormal;
//Можно указать что после завершения кода поток завершится автоматически:
MyThread.FreeOnTerminate:=true;
end;
end.
Ну вот, даже этот минимальный код позволяет поэкспериментировать с потоками и посмотреть, что они создаются в системе, работают, уничтожаются. Например, измените условие завершения потока:
MyThread.FreeOnTerminate:=false; //Поток не будет уничтожен после завершения работы
Теперь в Диспетчере Задач Windows можно наблюдать, что при каждом нажатии на кнопку Button1 в нашем приложении количество потоков в проекте Project1 увеличивается.
А теперь поместите в процедуру Execute такой оператор:
MyThread.Terminate;
Метод Terminate уничтожает данный экземпляр потока. Теперь при нажати кнопки в приложении количество потоков всё равно остаётся равным 1 (это главный поток приложения), так как сразу после создания новый поток уничтожается методом Terminate, и мы просто не успеваем заметить краткий миг его существания. Тем не менее, это означает, что код потока в процедуре Execute выполняется!
Ещё пример. Если в основной программе попробовать выполнить такой цикл:
while True do;
то приложение зависнет. А теперь поместите его в процедуру Execute. При нажатии на кнопку наш бесконечный цикл будет непрерывно выполняться в потоке, однако и приложение как целое не зависнет.
При работе с потоками необходимо учитывать приоритет создаваемых потоков. Так, если в предыдущем примере запустить не один поток, а два или больше, то компьютер станет очень заметно "тормозить". Это происходит потому что приоритет по умолчанию новых потоков - нормальный. Можно уменьшить его, задав
MyThread.Priority:=tpLower;
Этого достаточно, чтобы компьютер чувствовал себя более свободно. Вот таблица приоритетов:
Приоритет | Описание |
tpIdle | Низший приоритет. Поток получает время только тогда, когда операционая система находится в состоянии простоя. |
tpLowest | Приоритет на два пункта ниже нормального |
tpLower | Приоритет на один пункт ниже нормального |
tpNormal | Нормальный приоритет |
tpHigher | Приоритет на один пункт выше нормального |
tpHighest | Приоритет на два пункта выше нормального |
tpTimeCritical | Максимальный приоритет. Приоритет на уровне функций ядра операционной системы. |
Вот вам готовый проект работы c потоками, для экспериментов.
В продолжение темы нужно рассмотреть
Особености взаимодействия потоков с объектами VCL
Дело в том, что при работе с несколькими потоками в приложении необходимо гарантировать, что в данный момент только один из потоков может иметь доступ к свойствам и методам объекта VCL - визуального компонента Delphi. Для обеспечения этого условия в Delphi имеется специальный метод, в рамках которого и нужно вызывать процедуры, модифицирующие свойства и использующие методы визуальных компонентов.
Дата добавления: 2015-12-08; просмотров: 48 | Нарушение авторских прав