Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
Внизцикл в обьекте Найти похожие ветки
← →
михаил (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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.01 c