Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.13;
Скачать: CL | DM;

Вниз

цикл в обьекте   Найти похожие ветки 

 
михаил   (2004-02-02 00:23) [0]

Добрый вечер. Подскажите пожалуйста. Есть класс, в классе цикл.
Как мне зделать так чтобы при нажатии нам кнопку цикл останавливался и больше просчитывался. И начинать считать по новому.


 
Anatoly Podgoretsky ©   (2004-02-02 00:34) [1]

И с чем проблема?


 
михаил   (2004-02-02 00:43) [2]

вот тут. если цикл работает. то он то при нажатии на кнопку он
вроде бы начинает считать заново а когда кончает то ещё просчитывает то что раньше осталось.

procedure control.test ;
var xx, yy: Double;
xx1, yy1: Double;
xy, XxYy: double;
begin
xx1:=5000000; yy1:=5000000;
xxyy:=xx1*yy1;
while yy< yy1 do begin

while xx< xx1 do begin

xy:=xx*yy1+yy;
if startstop then
begin
exit;
end;
Form1.Edit1.text :=floattostr(round(xy/XxYy*100));
application.ProcessMessages ;
xx:=xx+1;
end;
yy:=yy+1;
end;
end;
procedure control.Start;
begin
startstop:=false;
end;

procedure control.Stop;
begin
StartStop:=true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
t:=control.Create ;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
t.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
t.Stop;
t.Start;

t.test ;
end;


 
Юрий Зотов ©   (2004-02-02 00:52) [3]

> михаил (02.02.04 00:23)

> Как мне зделать так чтобы при нажатии нам кнопку цикл
> останавливался и больше просчитывался. И начинать считать по
> новому.

> если цикл работает. то он то при нажатии на кнопку он
> вроде бы начинает считать заново а когда кончает то ещё
> просчитывает то что раньше осталось.

Я честно пытался понять, что же Вам нужно. Но так и не понял. Поэтому ответить на Ваш вопрос не могу. И буду сильно удивлен, если сможет кто-то другой, да еще и угадает, что же Вы все-таки имели в виду.

Поэтому, если Вы действительно хотите получить ответ, то очень советую задать вопрос так, чтобы он был понятен не только Вам одному.


 
михаил   (2004-02-02 01:03) [4]

1 Остановить цикл.
2. Начать считать новый.
3. К старому не возвращаться !!!

Зачем мне это нужно. Есть программа расчитывает очень интересные фракталы. Как в kpt. Мне нужно остановить вычисление старого фрактала и начать вычислять новый. Это просто аналог того что там происходит.
Когда я нажимаю два-три раза подряд на кнопку то программа просчитывает два три раза не останавливаясь. В реальной программа нажимать надо на listbox с номером фрактала. Но предыдущее вычисление не заканчивается.


 
lipskiy ©   (2004-02-02 01:07) [5]

Может так:

procedure control.test ;
var xx, yy: Double;
xx1, yy1: Double;
xy, XxYy: double;
begin
xx1:=5000000; yy1:=5000000;
xxyy:=xx1*yy1;
while yy< yy1 do begin

while xx< xx1 do begin

xy:=xx*yy1+yy;
if startstop then
begin
exit;
startstop:= false;
end;
Form1.Edit1.text :=floattostr(round(xy/XxYy*100));
application.ProcessMessages ;
xx:=xx+1;
end;
yy:=yy+1;
end;
end;
procedure control.Start;
begin
startstop:=false;
end;

procedure control.Stop;
begin
StartStop:=true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
t:=control.Create ;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
t.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
t.Stop;
while startstop do begin end;

t.test ;
end;


 
lipskiy ©   (2004-02-02 01:08) [6]

Тьфу, конечно наоборот:

begin
startstop:= false;
exit;
end;


 
lipskiy ©   (2004-02-02 01:10) [7]

И еще наверное так:

while startstop do Application.ProcessMessages;


 
михаил   (2004-02-02 01:19) [8]

не идёт.


 
lipskiy ©   (2004-02-02 01:26) [9]

Смотри пошагово (F7), смысл такой - перед повторным запуском цикла из первого должен сработать выход по exit, обязательно прежде, чем произведется новый вызов t.test


 
михаил   (2004-02-02 01:30) [10]

как это? не понял. можно пример.


 
lipskiy ©   (2004-02-02 01:36) [11]

Поставь брейкпойнты на две строки в твоем коде:
exit;
и
t.test;
Запускай выполнение. Брейкпойнт на exit должен произойти раньше, чем t.test.
Если это не так, то запускай программу пошагово, не F9 а F7 и жми F7 на каждый шаг и смотри последовательность выполнения команд.


 
Юрий Зотов ©   (2004-02-02 01:39) [12]

Вообще-то, напрашивается вынос вычислений в метод Execute потока (то есть, Ваш класс Control есть смысл сделать потомком TThread), но можно и без этого.

procedure TForm1.Form Create (Sender: TObject);
// Событие OnShow может происходить несколько раз и тогда
// возникнет утечка памяти. Поэтому надо использовать OnCreate.
begin
t := control.Create
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
t.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
// Выставляем StartStop. Кстати, советую сделать эту переменную
// полем объекта Control, а не просто глобальной переменной.
t.Stop;
// Здесь надо дать возможность циклу проверить StartStop и
// завершить свою работу, для чего следует вернуть выполнение
// программы в цикл. Поэтому делаем ОТЛОЖЕННЫЙ перезапуск
// цикла - посылаем в очередь сообщение.
PostMessage(Handle, WM_USER + 100, 0, 0);
// Теперь программа вернется в цикл, будет проверен StartStop и
// цикл завершится. После этого программа перейдет к обработке
// сообщений из очереди, при обработке нашего сообщения будет
// вызван метод t.test и цикл начнется СНАЧАЛА
end;

procedure TForm1.WMUserPlus100(var Message: TMessage);
// Это обработчик сообщения WM_USER + 100. Он запускает цикл.
begin
t.Test
end;


 
михаил   (2004-02-02 11:18) [13]

не понял.


 
Юрий Зотов ©   (2004-02-02 13:23) [14]

> михаил (02.02.04 11:18) [13]

Чего именно?


 
михаил   (2004-02-02 13:45) [15]

пожалуйста скинь рабочею програмку на bred24@rambler.ru.
Please.


 
Anatoly Podgoretsky ©   (2004-02-02 13:49) [16]

Деньги не приложены :-)


 
Юрий Зотов ©   (2004-02-02 14:33) [17]

> михаил (02.02.04 13:45) [15]

Привожу полный код рабочей программы с использованием ПОТОКА (потому что такие задачи лучше решать именно с потоком). Все, что будет неясно - СНАЧАЛА смотрим в справке и пытаемся понять САМОСТОЯТЕЛЬНО, а уже ПОТОМ, если все-таки остается непонятным, то спрашиваем здесь, ОК?

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;

type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject); // OnClick
procedure FormDestroy(Sender: TObject); // OnDestroy
private
FMyThread: TMyThread;
procedure StopThread;
procedure ThreadFinished(Sender: TObject);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

procedure TMyThread.Execute;
begin
MessageBox(0, "Start", "MyThread", MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
while not Terminated do Sleep(10);
MessageBox(0, "Finish", "MyThread", MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
end;

{ TForm1 }

procedure TForm1.StopThread;
begin
if FMyThread <> nil then
begin
FMyThread.Terminate;
if FMyThread.Suspended then FMyThread.Resume;
while FMyThread <> nil do Application.ProcessMessages
end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
StopThread;
FMyThread := TMyThread.Create(True);
FMyThread.FreeOnTerminate := True;
FMyThread.OnTerminate := ThreadFinished;
FMyThread.Resume
end;

procedure TForm1.ThreadFinished(Sender: TObject);
begin
FMyThread := nil
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
StopThread
end;

end.


 
михаил   (2004-02-02 22:37) [18]

Вообщем нашел ещё проще, авось пригодиться. Извеняюсь за беспокойство.

t.startstop :=true;
t:=nil;
t.Free;
t:=TObject.Create;
t.test ;


 
Германн ©   (2004-02-02 23:42) [19]

В такой последовательности строк сей вариант есть верное AV.


 
Anatoly Podgoretsky ©   (2004-02-03 00:53) [20]

AV здесь не грозит, разве что в первой строке, если объект не создан, не грозит еще и потому что это не откомпилируется из за последней строки, но только не AV


 
Юрий Зотов ©   (2004-02-03 12:28) [21]

> михаил (02.02.04 22:37) [18]

После t := nil метод t.Free ничего не сделает, объект реально не уничтожится и повиснет в памяти. Вслед за этим t:=TObject.Create создаст новый объект. Таким образом, при каждом проходе этой цепочки получаем утечку памяти в размере, равном InstanceSize объекта.

Вот такие пироги. Не лучше ли сделать НОРМАЛЬНО?


 
Тимохов ©   (2004-02-03 13:40) [22]


> Таким образом, при каждом проходе этой цепочки получаем
> утечку памяти в размере, равном InstanceSize объекта.

Плюс InstanceSize+4 байта - на запись в менеджере памяти под каждый выделенный блок памяти.


 
Тимохов ©   (2004-02-03 13:42) [23]

Блин, виноват

Плюс 4 байта - на запись в менеджере памяти под каждый выделенный блок памяти.



Страницы: 1 вся ветка

Текущий архив: 2004.02.13;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.029 c
6-38993
BOA_KAA
2003-12-08 16:00
2004.02.13
Автоматическая проверка полученной почты


7-39101
shurik_
2003-11-24 02:51
2004.02.13
реестр


1-38841
alless
2004-02-02 17:45
2004.02.13
RichEdit


14-39002
chtr
2004-01-22 07:34
2004.02.13
Иконку для D7


3-38667
Kelvin
2004-01-25 10:00
2004.02.13
DBListBox