
08.09.2014, 16:55
|
 |
Заблокирован
|
|
Регистрация: 29.08.2014
Адрес: Рязань
Сообщения: 26
Версия Delphi: D7, CB6, etc
Репутация: 10
|
|
Это чо такое было?
Цитата:
Сообщение от Heneken
Может и синхронизировать нечего..я как понял все в потоке делается
|
Ты прикалываешься, да? Даже боюсь предположить, что ты это серьёзно.
Там же обращения к VCL-объектам прямо в Execute()!
Маленький копипаст-ликбез из умной книжки:
Цитата:
Метод Synchronize()
В классе TThread определен метод Synchronize(), который позволяет вызывать некоторые из методов этого класса прямо из основного потока приложения. Определение метода Synchronize() имеет следующий вид:
Код:
procedure Synchronize(Method: TThreadMethod);
Параметр Method имеет тип TThreadMethod (означающий процедурный метод, не использующий никаких параметров), который определяется следующим образом:
Код:
type TThreadMethod = procedure of object;
Метод, передаваемый в качестве параметра Method, и является как раз тем методом, который затем выполняется из основного потока приложения. Возвращаясь к примеру с классом TTestThread, предположим, что мы хотим отобразить результат вычислений в строке редактирования на главной форме. Это можно сделать путем ввода в класс TTestThread метода, который вносит необходимые изменения в свойство Text строки редактирования, и последующего вызова этого метода с помощью процедуры Synchronize().
Предположим, этот метод называется GiveAnswer(). В листинге 11.1 представлен полный исходный Оод модуля ThrdU, который включает программную реализацию процесса обновления упомянутой выше строки редактирования на главной форме.
Листинг 11.1. Модуль ThrdU.PAS
Код:
unit ThrdU;
interface
uses Classes;
type
TTestThread = class(TThread)
private
Answer: integer;
protected
procedure GiveAnswer;
procedure Execute; override;
end;
implementation
uses
SysUtils, Main;
{ TTestThread }
procedure TTestThread.GiveAnswer;
begin
MainForm.Editl.Text := InttoStr(Answer);
end;
procedure TTestThread.Execute;
var
I: Integer; begin
FreeOnTerminate := True;
for I := 1 to 2000000 do begin
if Terminated then Break;
Inc(Answer, Round(Abs(Sin(Sqrt(I)))));
Synchronize(GiveAnswer);
end;
end;
end.
Мы уже знаем, что с помощью метода Synchronize() можно выполнять методы в контексте основного потока, но до сих пор мы обращались с ним как с таинственным черным ящиком. Мы знали, что он делает, но не знали как. Настало время приоткрыть завесу этой тайны.
При первом создании вторичного (или дополнительного) потока в приложении библиотека VCL создает и далее поддерживает скрытое окно потока в контексте своего основного потока. Единственная цель этого окна состоит в организации последовательности вызовов процедур, выполненных посредством метода Synchronize().
Метод Synchronize() сохраняет метод, заданный параметром Method, в закрытом поле FMethod и посылает определенное библиотекой VCL сообщение CM_EXECPROC в окно потока, передавая в качестве параметра lParam этого сообщения значение Self (в этом случае Self указывает на объект TThread). Когда процедура окна потока получает сообщение CM EXECPROC, она вызывает метод, заданный в поле FMethod с помощью экземпляра объекта TThread, переданного параметром lParam. Напомним, что поскольку это окно было создано в контексте основного потока, процедура окна для него также выполняется основным потоком. Следовательно, метод, указанный в поле FMethod, также вызывается основным потоком.
|
|