![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание потока, выполняющегося продолжительное время. [D7, WinXP]
Darrin © (2006-08-17 15:32:00)Доброго времени суток.
Столкнулся с проблемой создания потока (Thread), который бы выполнялся продолжительное время и при этом не загружал ресурсы машины на 100%.
Что сделал: создал наследника от TThread и перекрылметод Execute, в котором создал бесконечный цикл, дабы не выйти из метода execute.
Тестовый пример: (Форма на которой лежат 2 кнопки: одна запускаеТ поток, вторая останавливает его. В потоке, создаётся таймер на 1 секунду. При срабатывании таймера через метод Synchronizeв форму приложения передаётся параметр.)
<CODEb>
type
TForm3 = class;
TMyThread = class (TThread)
procedure TimerExecute(Sender: TObject);
private
FValue: Integer;
FTimer: TTimer;
FOwner: TForm3;
procedure SetValue;
protected
procedure DoTerminate; override;
procedure Execute; override;
end;
TForm3 = class(TForm)
Button1: TButton;
ProgressBar: TcxProgressBar;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FThread: TMyThread;
public
{ Public declarations }
procedure SetValue(Value: Integer);
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure TMyThread.TimerExecute(Sender: TObject);
begin
Inc(FValue);
Synchronize(SetValue);
end;
procedure TMyThread.SetValue;
begin
FOwner.SetValue(FValue);
end;
procedure TMyThread.DoTerminate;
begin
FTimer.Free;
inherited;
end;
procedure TMyThread.Execute;
begin
FValue := 0;
FTimer := TTimer.Create(nil);
FTimer.OnTimer := TimerExecute;
FTimer.Interval := 1000;
FTimer.Enabled := True;
while not Terminated do
begin
// Application.ProcessMessages;
end;
end;
procedure TForm3.Button1Click(Sender: TObject);
begin
FThread := TMyThread.Create(True);
FThread.FOwner := Self;
FThread.Resume;
end;
procedure TForm3.SetValue(Value: Integer);
begin
ProgressBar.Position := Value;
end;
procedure TForm3.Button2Click(Sender: TObject);
begin
FThread.Terminate;
end;
end.
В полне закономерно, что цикл
while not Terminated do
begin
// Application.ProcessMessages;
end;
вызвал 100% загрузку проца. (если раскоментить// Application.ProcessMessages;, ни чо хорошего тож не будет).
Подскажите, что нужно сделать, что бы выполнение потока не прекращалось, но и при этом не происходилобы 100%-ой загрузки проца.
Заранее спасибо.
Ketmar (2006-08-18 10:09:00) [1]ой. всё. понял. протупил проснумшись. %-)
Ketmar (2006-08-18 10:08:00) [2]> [9] atruhin © (18.08.06 09:53)
а зачем так сложно? что, Sleep(50*20) не поможет?
atruhin (2006-08-18 09:53:00) [3]> тут достаточно чего-то одного. или Sleep(), или обработки
> сообщений. %-)
Вот-вот. Нафига таймер то в таком потоке потоке?
while not Terminated do begin
inc(Count);
if Count mod 20 = 0 do begin
// делаем что то по таймеру
end;
Sleep(50);
end;
Ketmar (2006-08-17 15:56:00) [4]> [7] Darrin © (17.08.06 15:48)
тут достаточно чего-то одного. или Sleep(), или обработки сообщений. %-)
Darrin (2006-08-17 15:48:00) [5]>> Сергей М. ©
Пасиб. :) я тож пришёл именно к такому решению, просто думал есть другой - "более правильный способ"
>> tesseract
Благодарсвую,
Sleep(1);
Application.ProcessMessage;
тож работает
Ketmar (2006-08-17 15:47:00) [6]> [3] Сергей М. © (17.08.06 15:36)
"или так" (ц) анекдот
tesseract (2006-08-17 15:41:00) [7]
> Сергей М. © (17.08.06 15:36) [3]
так получше конечно :-)
Darrin (2006-08-17 15:37:00) [8]Вроде пробовал :-/ не помогало.... ща ещё разок попробую ...
Сергей М. (2006-08-17 15:36:00) [9]var
Msg: TMsg;
..
while not Terminated and GetMessage(Msg, 0, 0, 0) do
DispatchMessage(Msg)
Ketmar (2006-08-17 15:35:00) [10]эцих без гвоздей. %-)
делать Sleep(0) в цикле.
tesseract (2006-08-17 15:34:00) [11]sleep(10);