Текущий архив: 2007.01.21;
Скачать: CL | DM;
Вниз
Процессы Найти похожие ветки
← →
Neket (2006-12-28 11:08) [0]Подскажите как лучше сделать. Есть прога которая по таймеру (каждые 15 мин) запускает одну процедуру. Которая работает где-то мин 8-10. (Осуществляет опрос параметров оборудования). И при этом она не "реагирует" на внешнее воздействие (ну типа подвисает). Вопрос в следущем. Как сделать выполнение этой процедуры так чтобы можно в момент её выполнения я мог её остановить. Подскажите пожалуйста возможные варианты решения этого вопроса.
P.S.
Пробовал её выполнять отдельным процессом но это не помогло (всеравно подвисает) но я не исключаю что я его не совсем корректно запустил (процесс).
← →
palva © (2006-12-28 11:15) [1]Чтобы не подвисало, нужно запускать процедуру в отдельном потоке (Thread), а не в процессе.
Посмотрите для этого класс TThread. Несложно работать и через API функции (CreateThread и т. д.)
← →
Desdechado © (2006-12-28 11:21) [2]Вполне можно обойтись и без потоков.
Просто по нажатию кнопки "стоп" можно выставлять флаг, который время от времени проверять в той самой процедуре, опрашивающей оборудование.
← →
Neket (2006-12-28 11:23) [3]может я просто не совсем корректно объяснил по поводу процессов. Я использовал Thread Object
← →
Neket (2006-12-28 11:28) [4]2 Desdechado: Я думал по этому поводу... Но дело в том что у меня даже нажать на кнопку не получается. Все висит.
← →
iXT © (2006-12-28 11:32) [5]
> Neket (28.12.06 11:23) [3]
Thread - это не процесс, а поток (чувствуешь разницу). И чего, как делал? Как останавливал?
Ответ на вопрос ИМХО [1]. Других не задавал, ничего не описал. ???
← →
Джо © (2006-12-28 11:32) [6]Телепатирую. Вероятно, вся работа потока происходит в методе, вызываемом через Synchronize().
← →
Neket (2006-12-28 11:35) [7]2 Джо: ЗачОт... :-) Именно так и делал. Если это не правельно (что-то мне подсказывает что так оно и есть) то подскажите как необходимо сделать.
← →
Neket (2006-12-28 11:38) [8]
procedure SNMP_Q.Execute;
begin
Synchronize(StartOpros);
{ Place thread code here }
end;
← →
jack128 © (2006-12-28 11:41) [9]Neket (28.12.06 11:38) [8]
Ещё одна жертва Архангельского??
Надо так:
procedure SNMP_Q.Execute;
begin
StartOpros;
end;
А в Synchronize выноси, только тот код, который работает с интефейсом...
← →
Джо © (2006-12-28 11:42) [10]> [7] Neket (28.12.06 11:35)
> 2 Джо: ЗачОт... :-) Именно так и делал. Если это не правельно
> (что-то мне подсказывает что так оно и есть) то подскажите
> как необходимо сделать.
Syncronize() употребляется для выполнение переданного ей метода в контексте основного потока — того, в котором, собственно, выполняется пользовательский интерфейс (поэтому интерфейс и «виснет»). Соответственно, решение — не выполнять основную работу потока в этом методе, а выполнять его в Execute. Схема проста:procedure XXX.Execute;
begin
while not Terminated do
begin
//
// «основная» работа потока
//
// если нужно, вызываем Synchronize, чтобы взаимодействовать
// с основным потоком, например, интерфейсом программы
// тут проверяем условие выхода из потока,
// если нужно, вызываем Terminate
end;
end;
P.S. Телепатирую еще раз. Это Архангельский так научил с TThread работать? :D
← →
Desdechado © (2006-12-28 11:43) [11]> Но дело в том что у меня даже нажать на кнопку не получается. Все висит.
Вставь в процедуру опроса (она ж явно циклическая) в каждую итерацию Application.ProcessMessages
← →
Neket (2006-12-28 12:00) [12]2 Джо: Да нет... Просто методом проб и ошибок. Я впринципе раньше работал с TThread. Но забыл. :-(
2 ALL: Всем спасибо буду пробовать. Если что ещё спрошу.
P.S. Ещё раз всем спасибо.
← →
Ega23 © (2006-12-28 12:02) [13]
> Телепатирую. Вероятно, вся работа потока происходит в методе,
> вызываемом через Synchronize().
>
Мне, кстати, это тоже первое, что пришло в голову... :о)
← →
Джо © (2006-12-28 12:05) [14]> [13] Ega23 © (28.12.06 12:02)
>
> > Телепатирую. Вероятно, вся работа потока происходит в
> методе,
> > вызываемом через Synchronize().
> >
>
>
> Мне, кстати, это тоже первое, что пришло в голову... :о)
Значит, пора уже организовывать Клуб «Любителей» Архангельского :)
← →
Ega23 © (2006-12-28 12:15) [15]
> Значит, пора уже организовывать Клуб «Любителей» Архангельского
> :)
http://delphimaster.net/view/15-1166707484/
аккурат неделю назад... :о)
← →
Neket (2006-12-28 16:16) [16]Все вроде заработало... Нотеперь не пойму.... А как правельно "прибить" процесс? т.е.
procedure TForm1.Button1Click(Sender: TObject);
begin
snmp_p.Create(false); // Создаем процесс
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
????????????? // Прибиваем процесс
end;
← →
Джо-со-смарта (2006-12-28 16:34) [17]Смотри мой пример на предмет терминейт. Только помни, что терминейтед -- только флаг и тебе в ходе выполнения потока самому нужно его периодически проверять и выходить из екзекьют.
← →
Neket (2006-12-28 16:36) [18]2 Джо-со-смарта: А какой пример?
← →
Ega23 © (2006-12-28 16:38) [19]TMyTread.Execute
beign
While not Terminated do Work;
end;
← →
Джо-со-смарта (2006-12-28 16:38) [20]Он у меня один в этой ветке.
← →
Neket (2006-12-28 16:58) [21]2 Джо: Я просто немного запутался с никами...
Насколько я понял While not Terminated do Work это остановка выполнения процесса. Но а как его прибить полностью? К примеру в случае FormClose
пробовал делать так:procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Potok.Destroy;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Potok.Terminate;
end;
Но если закрываю приложение то оно у меня зависает. Подскажите пожалуйста где ошибка?
← →
Джо © (2006-12-28 17:19) [22]Еще раз.
Terminate — выставляет свойство Terminated в True. Ты в своем цикле (или где-там у тебя обработка) периодически проверяешь этот свойство, и, если оно True, просто выходишь из тела метода Execute.
> [21] Neket (28.12.06 16:58)
> Насколько я понял While not Terminated do Work это остановка
> выполнения процесса.
Нет. Это собственно сама работа твоего потока.
← →
Джо © (2006-12-28 17:19) [23]И не забудь перед запуском потока выставить FreeOnTerminate. Тогда экземпляр объекта будет автоматически освобожден.
← →
Джо © (2006-12-28 17:21) [24]Схема словами:
procedure XXX.Execute;
begin
// что-то сделали
// проверим, если True, то выходим из Execute
// что-то сделали
// проверим, если True, то выходим из Execute
// что-то сделали
// проверим, если True, то выходим из Execute
// ...
end;
← →
Джо © (2006-12-28 17:22) [25]> проверим, если True,
проверим, если Terminated = True
Сорри.
← →
Mickey74 © (2006-12-28 21:39) [26]Не очень хороший способ, но попробуй:
Application.ProcessMessages;
← →
Neket (2006-12-29 10:27) [27]2 ДЖО: Спасибо очень помог...
Но возник ещё один вопрос как определить был ли создан потокsnmp_p.Create(false); ?
Это необходимо чтобы в случае закрытия формыTForm1.FormClose
при запущенном потоке чтобы поток очередную итерацию цикла доработал до конца а потом закрылся. Да и плюс ко всему, если поток не был создан и закрывается форма то вылитает ошибка
т.е. грубо говоря надо чтобы при событии OnFormClose отрабатывалась что-то вы этом роде >>>if Potok.Terminate=false then Potok.Terminate;
Но как это правельно описать я к сожелаения не знаю.
← →
Ega23 © (2006-12-29 10:32) [28]
> т.е. грубо говоря надо чтобы при событии OnFormClose отрабатывалась
> что-то вы этом роде >>> if Potok.Terminate=false then Potok.
> Terminate; Но как это правельно описать я к сожелаения не
> знаю.
if Assigned(DataThread) then // Если поток создан
begin
DataThread.Terminate; // Послали убийство
WaitForSingleObject(DataThread.Handle, 1000); // Подождали, чтобы убился
end;
← →
evvcom © (2006-12-29 10:41) [29]> [27] Neket (29.12.06 10:27)
> чтобы в случае закрытия формы TForm1.FormClose при запущенном
> потоке чтобы поток очередную итерацию цикла доработал до
> конца а потом закрылся
Это поток сам проверяет в своем деструкторе. См. исходники.
> при событии OnFormClose отрабатывалась что-то вы этом роде
> >>> if Potok.Terminate=false then Potok.Terminate;
Во-первых,if Potok.Terminated
, а во-вторых, это неважно. Просто делайPotok.Terminate
. См. исходники.
← →
evvcom © (2006-12-29 10:44) [30]> [28] Ega23 © (29.12.06 10:32)
Достаточно просто DataThread.Free; во Free проверится Assigned, а в Destroy выполнится Terminate и WaitFor
← →
EvChul © (2006-12-29 10:47) [31]Ega23 © (29.12.06 10:32) [28]
А не лучше ли ?if Assigned(DataThread) then // Если поток создан
begin
DataThread.Terminate; // Послали убийство
DataThread.WaitFor; // Подождали, чтобы убился
end;
← →
Ega23 © (2006-12-29 10:55) [32]
> Достаточно просто DataThread.Free; во Free проверится Assigned,
> а в Destroy выполнится Terminate и WaitFor
Да? НУ ладно, буду знать, я с потоками мало работал.
← →
Neket (2006-12-29 10:59) [33]Всем спасибо за помощь.... Разобрался... Попробовал все методы и работают все три но как показала практика что наиболее практичнее для ленивых ;-) писать
DataThread.Free;
← →
evvcom © (2006-12-29 11:03) [34]> [33] Neket (29.12.06 10:59)
А самые работящие могут написать свой или хотя бы скопировать весь код TThread в свой модуль и пользовать его. :)
Страницы: 1 вся ветка
Текущий архив: 2007.01.21;
Скачать: CL | DM;
Память: 0.55 MB
Время: 0.07 c