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

Ognev

ex-Team DUMPz
Местный
Регистрация
20 Авг 2004
Сообщения
2,079
Реакции
908
Credits
0
Всем доброго времени суток!

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

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

Guard

Premium
Регистрация
6 Мар 2004
Сообщения
58
Реакции
2
Credits
223
Если нужна точность, то можно так :

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

Ognev

ex-Team DUMPz
Местный
Регистрация
20 Авг 2004
Сообщения
2,079
Реакции
908
Credits
0
Lord Phoenix,
Sleep() посмотрю. Искал что-то подобное но не нашел.

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

Guard

Premium
Регистрация
6 Мар 2004
Сообщения
58
Реакции
2
Credits
223
Lord Phoenix,
Sleep() посмотрю. Искал что-то подобное но не нашел.

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

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

ploki

Местный
Регистрация
16 Май 2005
Сообщения
237
Реакции
180
Credits
0
Постмотри в MSDN хорошие статьи про Sleep, SleepEx и WaitForSingleObject(Ex). Расмматривается много случаев применения. Кстати, Sleep(0) также часто полезна - она отдаёт остаток текущего кванта системе.

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

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

Ognev

ex-Team DUMPz
Местный
Регистрация
20 Авг 2004
Сообщения
2,079
Реакции
908
Credits
0
Спасибо всем за ответы!
Однако, при Sleep() программа просто висит. Про пустой цикл я уже говорил - не хочется нагружать процессор непрерывной проверкой окончания таймаута. Кстати, вместо GetTickCount там можно использовать обычный Time, например. К тому же, я не крутой написатель кода, по этому хотелось бы не ссылки на книги ))) а более менее готовые решения. Есть ли еще какие-нибудь предложения? Может можно с таймером чего-нибудь навернуть.
 

Guard

Premium
Регистрация
6 Мар 2004
Сообщения
58
Реакции
2
Credits
223
Спасибо всем за ответы!
Однако, при Sleep() программа просто висит. Про пустой цикл я уже говорил - не хочется нагружать процессор непрерывной проверкой окончания таймаута. Кстати, вместо GetTickCount там можно использовать обычный Time, например. К тому же, я не крутой написатель кода, по этому хотелось бы не ссылки на книги ))) а более менее готовые решения. Есть ли еще какие-нибудь предложения? Может можно с таймером чего-нибудь навернуть.

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

ploki

Местный
Регистрация
16 Май 2005
Сообщения
237
Реакции
180
Credits
0
Разница очень большая.

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


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

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

ploki

Местный
Регистрация
16 Май 2005
Сообщения
237
Реакции
180
Credits
0
Как вариант, предлагаю использовать второй поток. То есть создать
TThread, а в нём на OnExecute - твою функцию.

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

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

ploki

Местный
Регистрация
16 Май 2005
Сообщения
237
Реакции
180
Credits
0
Как вариант, предлагаю использовать второй поток. То есть создать
TThread, а в нём на OnExecute - твою функцию.

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

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

Anakin

Турист
Регистрация
5 Окт 2006
Сообщения
36
Реакции
1
Credits
72
А зачем изобретать велосиперд?
TTimer И задерживай на скока душе угодно.
 

Guard

Premium
Регистрация
6 Мар 2004
Сообщения
58
Реакции
2
Credits
223
А зачем изобретать велосиперд?
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
Местный
Регистрация
20 Авг 2004
Сообщения
2,079
Реакции
908
Credits
0
Все не было времени занятся этим вопросом, а тут уж раз тему всколыхнули, то решил написать, что именно было у меня )))
Есть телефон, в который прога по эмулированному Com порту посылает команды. В зависимости от некоторых условий, иногда есть необходимость задержать отправку команды на некоторое время. Грубо говоря, уже был написан рабочий код, когда такая необходимость (в отсрочке посылки команды) возникла. Ну и тут же возникло естественное желание, написать несколько строчек кода, которые делали бы это, а не перекраивать структуру процедур. Это я к вопросу о рекомендации конкретного варианта ))) К слову замечу, что перекраивать процедуры пришлось по другому поводу, поэтому лично для меня этот вопрос имеет чисто методическое значение )))