![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
||||
|
||||
|
Допустим есть некий поток:
Код:
unit MVCThread;
interface
uses
Classes;
type
TMVCCreateStruct = record
port:string;
baudrate:Integer;
end;
TMVCThread = class(TThread)
private
FSomeProp: Boolean;
procedure SyncProc;
protected
procedure Execute; override;
public
property SomeProp:Boolean read FSomeProp write FSomeProp;
end;
implementation
{
Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TMVCThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
or
Synchronize(
procedure
begin
Form1.Caption := 'Updated in thread via an anonymous method'
end
)
);
where an anonymous method is passed.
Similarly, the developer can call the Queue method with similar parameters as
above, instead passing another TThread class as the first parameter, putting
the calling thread in a queue with the other thread.
}
{ TMVCThread }
procedure TMVCThread.Execute;
begin
{ Place thread code here }
while not Terminated do
begin
Sleep(100);
if FSomeProp then
Synchronize(SyncProc);
end;
end;
procedure TMVCThread.SyncProc;
begin
//код
end;
end. |
|
#2
|
||||
|
||||
|
Цитата:
![]() |
|
#3
|
||||
|
||||
|
можно через модификатор, устанавливать флаг, в цике казнения смотреть на этот флаг и только в том случае, если он установлен - менять значение переменной.
|
|
#4
|
||||
|
||||
|
Однако подобное свойство есть.
Например: FOnTerminate. Причем если там посмотреть вызовы, то проверки выполняются в каждой процедуре (вызовы одна из другой, смотрите исходники TThread), следовательно теоретически возможно изменение свойства между вызовами. |
|
#5
|
||||
|
||||
|
У меня в одном приложении примерно так работает. Проблем никаких не наблюдаю. Главное не забывать пинать поток когда нужно.
Код:
procedure TMySuperDuperThread.Execute;
begin
while not Terminated do
if not Suspended then
begin
if SomeProp then
ApplySomeProcedure
else
Suspend;
end;
end; |
|
#6
|
|||
|
|||
|
И самое главное, нафига внутри Execute вся полезная работа делается под Synchronize ?
|
|
#7
|
||||
|
||||
|
Цитата:
![]() |
|
#8
|
||||
|
||||
|
Цитата:
Цитата:
Код:
Sleep(100); |
|
#9
|
||||
|
||||
|
для скалярного Boolean сгодится и так. посмотри на свойство Terminated и метод Terminate у TThread:
Код:
TThread = class private FTerminated: Boolean; protected property Terminated: Boolean read FTerminated; public procedure Terminate; procedure TThread.Terminate; begin FTerminated := True; end; вполне естественно вызывать из основного потока методы Terminate и WaitFor для завершения и ожидания работы потока, когда в самом потоке может быть проверка Terminated, как в первом посте. |
|
#10
|
||||
|
||||
|
Цитата:
Код:
Thread := TMyThread.Create(True); Thread.OnTerminate := MyMethod; // Здесь спокойно можно присваивать Thread.Resume; Thread.OnTerminate := MyMethod; // А вот здесь уже нельзя Цитата:
Для Terminated это не страшно, так как единственное его предназначение это: Код:
while not Terminated do begin ... if Terminated then Break; // Это тоже не повлияет на логику ... end; |
|
#11
|
||||
|
||||
|
а вопрос был на сколько безопасно устанавливать такое свойство из основного потока? ответ - полностью безопасно. нужная процедура будет успешно выполняться при установленном свойстве.
чтобы не гадать что будет с логикой работы нужно каждую ситуацию рассматривать отдельно. к примеру если это чекбокс (при изменении его состояния меняется значение свойства потока), который информирует поток о том что нужно что-то обновлять на форме, то такой вариант очень даже сгодиться и не нужно изучать раздел "Synchronization Functions". добавлено позже пока отвлекся на работу и писал сообщение пример уже описали))) добавлено еще позже вариант ~TB~ мне тоже не понятен Последний раз редактировалось NumLock, 20.09.2012 в 11:17. |