Пауза в выполнении кода

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,105
Reaction score
902
Age
25
Всем доброго времени суток!

Может это звучит глупо, но возникла у меня необходимость в середине процедуры (при выполнении некоторых условий) поставить паузу. Т.е. возобновить выполнение кода через некоторый промежуток времени. Путем некоторого усложнения я обошел эту проблему, но вопрос остался:
Можно ли в Delphi написать некоторую, например, процедуру, вызов которой бы приостанавливал выполнение кода. Хотелось бы реализовать это грамотно, не напрягая систему, например, пустым циклом.

Спасибо всем, кто отзовется.
 

Guard

Premium
Joined
Mar 5, 2004
Messages
58
Reaction score
2
Age
50
Location
Тула
Если нужна точность, то можно так :

procedure TForm1.Button1Click(Sender: TObject);
var
t: integer;
begin
t := GetTickCount;
repeat
Application.ProcessMessages
until
GetTickCount - t >= 1000;
end;
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,105
Reaction score
902
Age
25
Lord Phoenix,
Sleep() посмотрю. Искал что-то подобное но не нашел.

Guard,
не знаю что такое GetTickCount, но помоему, это тот же пустой цикл, только что приложение при этом не будет висеть, как без ProcessMessages.
 

Guard

Premium
Joined
Mar 5, 2004
Messages
58
Reaction score
2
Age
50
Location
Тула
Lord Phoenix,
Sleep() посмотрю. Искал что-то подобное но не нашел.

Guard,
не знаю что такое GetTickCount, но помоему, это тот же пустой цикл, только что приложение при этом не будет висеть, как без ProcessMessages.

Ну незнаю как ты искал Sleep живет в SysUtils и всегда подключена.
GetTickCount живет в Windows. Обе функции используют Kernel.dll
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Постмотри в MSDN хорошие статьи про Sleep, SleepEx и WaitForSingleObject(Ex). Расмматривается много случаев применения. Кстати, Sleep(0) также часто полезна - она отдаёт остаток текущего кванта системе.

Также глянь статью "Suspending Thread Execution".

Если нужно много информауции на эту тему - смотри Д. Рихтер "Професиональное программирование под Windows" - Da Best!!!
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,105
Reaction score
902
Age
25
Спасибо всем за ответы!
Однако, при Sleep() программа просто висит. Про пустой цикл я уже говорил - не хочется нагружать процессор непрерывной проверкой окончания таймаута. Кстати, вместо GetTickCount там можно использовать обычный Time, например. К тому же, я не крутой написатель кода, по этому хотелось бы не ссылки на книги ))) а более менее готовые решения. Есть ли еще какие-нибудь предложения? Может можно с таймером чего-нибудь навернуть.
 

Guard

Premium
Joined
Mar 5, 2004
Messages
58
Reaction score
2
Age
50
Location
Тула
Спасибо всем за ответы!
Однако, при Sleep() программа просто висит. Про пустой цикл я уже говорил - не хочется нагружать процессор непрерывной проверкой окончания таймаута. Кстати, вместо GetTickCount там можно использовать обычный Time, например. К тому же, я не крутой написатель кода, по этому хотелось бы не ссылки на книги ))) а более менее готовые решения. Есть ли еще какие-нибудь предложения? Может можно с таймером чего-нибудь навернуть.

На сколько я в этом разбираюсь, разницы никакой. Все реализуется тем же циклом и время с железа зависит только от места нахождения этого цикла в твоей проге или где-то ещё(kernel.dll или в реализации того же таймера). Если цикл ты сам крутишь, то можешь отдавать время другим задачам или например делать эту паузу более точной.
 
Last edited by a moderator:

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Разница очень большая.

При Sleep(Ex) программа не висит, особенно, если она многопоточная. Она говорит менеджеру процесоов, что не надо данному её потоку процессорного времени на некоторое время или до наступления некоторого события.
Сама по себе процедура Sleep используется редко, особенно главным потоком процесса, в котором обрабатываются события интерфейса. SleepEx часто используется при асинхронном вводе-выводе.
В остальных случаях используются функции из группы WaitFor... .
Ожидать при этом можно много чего - сигнала от таймера, семафора, мьютекса, файла, процесса/потока и др.


Ognev, если расскажешь, какие у тебя условия для ожидания - порекомендую конкретный вариант.

P.S. А книжка Рихтера - must read для любого WIN32 программиста.
 
Last edited by a moderator:

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Как вариант, предлагаю использовать второй поток. То есть создать
TThread, а в нём на OnExecute - твою функцию.

Ещё вариант приостановки с использованием объектов ядра:
Code:
var
  h: HWND; 
begin
... 
h:=CreateEvent(nil, true, false, 'Имя'); 
WaitForSingleObject(h, <Максимальная задержка>);
СloseHandle(h);
...
end;

А где- то в другом месте можно использовать SetEvent(h) для того, чтобы была не <Максимальная задержка>, а меньше.
В MSDN есть статья "Using Event Objects" с хорошими примерами.
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Как вариант, предлагаю использовать второй поток. То есть создать
TThread, а в нём на OnExecute - твою функцию.

Ещё вариант приостановки с использованием объектов ядра:
Code:
var
  h: HWND; 
begin
... 
h:=CreateEvent(nil, true, false, 'Имя'); 
WaitForSingleObject(h, <Максимальная задержка>);
СloseHandle(h);
...
end;

А где- то в другом месте можно использовать SetEvent(h) для того, чтобы была не <Максимальная задержка>, а меньше.
В MSDN есть статья "Using Event Objects" с хорошими примерами.
 

Anakin

Member
Joined
Oct 5, 2006
Messages
36
Reaction score
1
Age
42
Location
Zimbabve
А зачем изобретать велосиперд?
TTimer И задерживай на скока душе угодно.
 

Guard

Premium
Joined
Mar 5, 2004
Messages
58
Reaction score
2
Age
50
Location
Тула
А зачем изобретать велосиперд?
TTimer И задерживай на скока душе угодно.

Я понимаю ты хочешь сделать приблизительно так :

Бросаем компонент Timer1. Когда надо сделать паузу пишем :

i:= False;
Timer1.Interval:= 1000; // Задаем время
Timer1.Enabled:= True;
while not i then Application.ProcessMesages;

Соответственно в OnTimer :

i:= True; // Случилось :)

Учитываем код самого TTimer и вот у нас и получился велосипедик, четырехколесный, БАБОЧКА :) сам на таком в детстве ездил. Почему такой вариант ты считаешь лучше Sleep(1000) я не понимаю :)
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,105
Reaction score
902
Age
25
Все не было времени занятся этим вопросом, а тут уж раз тему всколыхнули, то решил написать, что именно было у меня )))
Есть телефон, в который прога по эмулированному Com порту посылает команды. В зависимости от некоторых условий, иногда есть необходимость задержать отправку команды на некоторое время. Грубо говоря, уже был написан рабочий код, когда такая необходимость (в отсрочке посылки команды) возникла. Ну и тут же возникло естественное желание, написать несколько строчек кода, которые делали бы это, а не перекраивать структуру процедур. Это я к вопросу о рекомендации конкретного варианта ))) К слову замечу, что перекраивать процедуры пришлось по другому поводу, поэтому лично для меня этот вопрос имеет чисто методическое значение )))
 
Top