Наши преимущества

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

Ognev

ex-Team ITcluB
Команда форума
Credits
0
Всем доброго времени суток!

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

Спасибо всем, кто отзовется.
 
Если нужна точность, то можно так :

procedure TForm1.Button1Click(Sender: TObject);
var
t: integer;
begin
t := GetTickCount;
repeat
Application.ProcessMessages
until
GetTickCount - t >= 1000;
end;
 
Lord Phoenix,
Sleep() посмотрю. Искал что-то подобное но не нашел.

Guard,
не знаю что такое GetTickCount, но помоему, это тот же пустой цикл, только что приложение при этом не будет висеть, как без ProcessMessages.
 
Lord Phoenix,
Sleep() посмотрю. Искал что-то подобное но не нашел.

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

Ну незнаю как ты искал Sleep живет в SysUtils и всегда подключена.
GetTickCount живет в Windows. Обе функции используют Kernel.dll
 
Постмотри в MSDN хорошие статьи про Sleep, SleepEx и WaitForSingleObject(Ex). Расмматривается много случаев применения. Кстати, Sleep(0) также часто полезна - она отдаёт остаток текущего кванта системе.

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

Если нужно много информауции на эту тему - смотри Д. Рихтер "Професиональное программирование под Windows" - Da Best!!!
 
Спасибо всем за ответы!
Однако, при Sleep() программа просто висит. Про пустой цикл я уже говорил - не хочется нагружать процессор непрерывной проверкой окончания таймаута. Кстати, вместо GetTickCount там можно использовать обычный Time, например. К тому же, я не крутой написатель кода, по этому хотелось бы не ссылки на книги ))) а более менее готовые решения. Есть ли еще какие-нибудь предложения? Может можно с таймером чего-нибудь навернуть.
 
Спасибо всем за ответы!
Однако, при Sleep() программа просто висит. Про пустой цикл я уже говорил - не хочется нагружать процессор непрерывной проверкой окончания таймаута. Кстати, вместо GetTickCount там можно использовать обычный Time, например. К тому же, я не крутой написатель кода, по этому хотелось бы не ссылки на книги ))) а более менее готовые решения. Есть ли еще какие-нибудь предложения? Может можно с таймером чего-нибудь навернуть.

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

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


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

P.S. А книжка Рихтера - must read для любого WIN32 программиста.
 
Последнее редактирование модератором:
Как вариант, предлагаю использовать второй поток. То есть создать
TThread, а в нём на OnExecute - твою функцию.

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

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

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

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

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

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

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

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

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

Учитываем код самого TTimer и вот у нас и получился велосипедик, четырехколесный, БАБОЧКА :) сам на таком в детстве ездил. Почему такой вариант ты считаешь лучше Sleep(1000) я не понимаю :)
 
Все не было времени занятся этим вопросом, а тут уж раз тему всколыхнули, то решил написать, что именно было у меня )))
Есть телефон, в который прога по эмулированному Com порту посылает команды. В зависимости от некоторых условий, иногда есть необходимость задержать отправку команды на некоторое время. Грубо говоря, уже был написан рабочий код, когда такая необходимость (в отсрочке посылки команды) возникла. Ну и тут же возникло естественное желание, написать несколько строчек кода, которые делали бы это, а не перекраивать структуру процедур. Это я к вопросу о рекомендации конкретного варианта ))) К слову замечу, что перекраивать процедуры пришлось по другому поводу, поэтому лично для меня этот вопрос имеет чисто методическое значение )))
 
Верх