Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Альтернатива GetTickCount   Найти похожие ветки 

 
Unknown user ©   (2012-03-13 20:03) [0]

Подскажите, пожалуйста чем можно заменить такую конструкцию

 Start := GetTickCount;
 while (FReceivedData = nil) and (GetTickCount - Start < WaitTime) do
   Application.ProcessMessages;

Здесь цикл завершится по истечению таймаута, либо при получении данных.

Оказалось, что GetTickCount возвращает правильные значения только первые 50 дней непрерывной работы системы.


 
QAZ   (2012-03-13 20:16) [1]

идиотская конструкция


 
Anatoly Podgoretsky ©   (2012-03-13 20:18) [2]

> Unknown user  (13.03.2012 20:03:00)  [0]

Не новость.


 
Sha ©   (2012-03-13 20:18) [3]

а мне интересно, чему равно WaitTime


 
Jeer ©   (2012-03-13 20:19) [4]

И что ?
Таймаут на 50 дней ?

GetTickCount всегда возвращает "правильные" значения по модулю.


 
Sha ©   (2012-03-13 20:23) [5]

и еще неправильные - это какие ?
и еще где все эти операторы написаны?


 
Sha ©   (2012-03-13 20:26) [6]

и еще часы на стене - они правильные значения показывают?


 
Jeer ©   (2012-03-13 20:33) [7]


> Подскажите,


Подсказываю:
GetSystemTimeAsFileTime(..)

этого должно надолго хватить "правильно" показывать время.


 
sniknik ©   (2012-03-13 20:37) [8]

> чем можно заменить такую конструкцию
если ждать аж 50 дней то календарем...  :)

> GetTickCount возвращает правильные значения только первые 50 дней непрерывной работы системы.
а дальше что неправильные? все возвращается правильно, в соответствии с документацией...
а то, что переменная возвращаемого значения возрастает без учета переполнения (в соответствии с докой), довольно легко учесть в условии.


 
Sha ©   (2012-03-13 20:40) [9]

там типа учтено, проблема в другом


 
Dimka Maslov ©   (2012-03-13 21:26) [10]

Для начала нужно подумать, а что даёт такая "конструкция"? Она не даёт ничего. Сообщения обрабатываются, форма выглядит и работает нормально. Если нужен таймер - надо пользоваться таймером, там тоже в процессе ожидания события всё работает. На худой конец можно воспользоваться rtdsc. Но у него тоже время ограничено.


 
sniknik ©   (2012-03-13 22:24) [11]

> там типа учтено
там типа, без типа, нельзя сказать.
например
var
 start, finish: Int64;
begin
 start := DWORD(-1) - 10;
 finish:= 10;
 ShowMessage(IntToStr(finish - start));
end;

или
var
 start: DWORD;
 finish: integer;
begin
...


 
DVM ©   (2012-03-13 22:54) [12]


> Unknown user ©   (13.03.12 20:03) 
> Подскажите, пожалуйста чем можно заменить такую конструкцию
>
>  Start := GetTickCount;
>  while (FReceivedData = nil) and (GetTickCount - Start <
> WaitTime) do
>    Application.ProcessMessages;

Эта конструкция результат желания одновременно задержать выполнение программы и обрабатывать сообщения Windows. Смысла не имеет никакого.
Данная конструкция заменяется таймером. В таймере проверка какого либо флага. Если нужно запретить в программе выполнять какие либо действия, то опять же проверяем флаг перед их выполнением. И не нужно крутить циклы!!!

А ждать очень большие интервалы времени лучше с помощью WaitableTimer (CreateWaitableTimer, SetWaitableTimer)


 
Sha ©   (2012-03-13 23:15) [13]

sniknik ©   (13.03.12 22:24) [11]

Еще типа byte может быть.
Раз работаем с GetTickCount, то имеет смысл объявить
var Start, WaitTime: dword;
и все учтется автоматом.

Если в главном потоке проверяем FReceivedData,
то, вероятно, в другом ее меняют.
Поэтому имеет смысл оттуда просто послать сообщение,
и тогда вся эта "конструкция" нафиг не нужна.


 
sniknik ©   (2012-03-13 23:34) [14]

> и все учтется автоматом.
спасибо кэп!


 
Sha ©   (2012-03-13 23:47) [15]

все благодарности - компилятору, это он предупреждения выдает


 
sniknik ©   (2012-03-14 00:09) [16]

а ты проверь... вот хотя бы первое приведенное в [11].


 
antonn ©   (2012-03-14 00:16) [17]


> DVM ©   (13.03.12 22:54) [12]
>
>
> > Unknown user ©   (13.03.12 20:03)
> > Подскажите, пожалуйста чем можно заменить такую конструкцию
> >
> >  Start := GetTickCount;
> >  while (FReceivedData = nil) and (GetTickCount - Start
> <
> > WaitTime) do
> >    Application.ProcessMessages;
>
> Эта конструкция результат желания одновременно задержать
> выполнение программы и обрабатывать сообщения Windows. Смысла
> не имеет никакого.

у меня вместо "Application.ProcessMessages" вызывается обработчик, и в зависимости от класса это может быть и таймер, в отдельном потоке и не завязаный на оконные сообщения. Задавался тем же вопросом что и автор: что делать после 49 дней. Но мне проще, я могу сервер ребутнуть ради своей службы, потому не стал особо мучаться.


 
antonn ©   (2012-03-14 00:18) [18]

вот, кстати http://forum.sources.ru/index.php?showtopic=334024


 
Anatoly Podgoretsky ©   (2012-03-14 00:25) [19]

> antonn  (14.03.2012 00:16:17)  [17]

Умножить на количество кругов


 
DVM ©   (2012-03-14 00:27) [20]


> в отдельном потоке и не завязаный на оконные сообщения

там WaitableTimer + WaitForXXXObjects самое оно.


 
Sha ©   (2012-03-14 00:43) [21]

> а ты проверь... вот хотя бы первое приведенное в [11].

Зачем? Я арифметику знаю.
Нормальный программист если в коде ниже машинально напишет первое объявление,
прочитав предупреждение, тут же исправит на второй вариант.
Профнепригодный на int64. Вот и весь сказ.

procedure TForm1.Timer1Timer(Sender: TObject);
var
 Start, WaitTime: integer; //warning
 Start, WaitTime: dword; //OK
 FReceivedData: pointer;
begin
 FReceivedData:=nil;
 WaitTime:=1000;
 Start := GetTickCount;
 while (FReceivedData = nil) and (GetTickCount - Start < WaitTime) do
   Application.ProcessMessages;
end;


 
Sha ©   (2012-03-14 00:49) [22]

> antonn ©   (14.03.12 00:18) [18]

повеселили ребята


 
Unknown user ©   (2012-03-14 17:19) [23]

Тут целые баталии развернулись по поводу GetTickCount :)

Это был мой недосмотр...Конец рабочего дня, сказывается усталость :)

Ошибку нашел почти сразу, после создания этого поста. Забыл отписать. Start у меня была объявлена как Integer.

Start := GetTickCount;
while (FReceivedData = nil) and (GetTickCount - Start < WaitTime) do
  Application.ProcessMessages;


Здесь нет другого потока. FReceivedData создается также в первичном потоке, при обработке сообщений из очереди. WaitTime = 5000.

Таймер здесь считаю неуместным, так как выполнение программы в этой точке нужно остановить. Асинхронная обработка усложнит код.

Никто из вас не использует такой подход?


 
QAZ   (2012-03-14 17:23) [24]


> Start у меня была объявлена как Integer.

а какого фака не кардинал?
и где связь между 5 секунд и 50 суток?


 
sniknik ©   (2012-03-14 17:24) [25]

> Никто из вас не использует такой подход?
нет конечно.

> так как выполнение программы в этой точке нужно остановить.
ну так ты ее не останавливаешь (в этом коде, а то счаз опять вылезет не упомянутая мелочь типа типа).... просто подменяешь обработчик сообщений.


 
Unknown user ©   (2012-03-14 17:28) [26]

>а какого фака не кардинал?

ну я же говорю, пьян был

>и где связь между 5 секунд и 50 суток?

ну тут все просто, сервак уже отработал больше 25 суток без перезагрузки. Поэтому Start переполнялся и оказывался < 0. GetTickCount же возвращала значение больше 2^31 и цикл сразу завершался.


 
QAZ   (2012-03-14 17:35) [27]


> Поэтому Start переполнялся и оказывался < 0

я и говорю какого фака интежер?


 
Jeer ©   (2012-03-14 17:35) [28]


> сказывается усталость :)



> ну я же говорю, пьян был


О как!  В данную эпоху понимается: "пьян был" == "устал" :)

Не дай хрен такого работника никому.


 
Jeer ©   (2012-03-14 17:42) [29]


> я и говорю какого фака интежер?


Да им все равно: интежер, ворд, байт, бит..

Напомню реальную историю, случившуюся чуть ранее вхождения Фобоса в грунт.

Дали задачку на кодирование телеметрии с борта одному "толковому" студенту.
Ради экономии памяти он принял, что байт - это 6 бит.
В итоге, наземная служба принимает данные и тихо хренеет - вариации положения спутника на орбите превышают все доступные землянам технологии.
Разобрались, отчитали, отчислили.
Телеметрию пришлось перекодировать уже на земле, хоть что-то, но сумели выцепить.


 
QAZ   (2012-03-14 17:47) [30]

дык еще и книжки пишут по принципу "типов integer и real вам будет достаточно для большинства задач" :)


 
Unknown user ©   (2012-03-14 17:50) [31]

>Не дай хрен такого работника никому.

Ну не знаю, почему-то ценят.

Не верю, что вы пишите программы без багов и никогда не "тупите". С каждым бывает...

Как насчет моего вопроса?


 
Mystic ©   (2012-03-14 17:58) [32]

Идем в MSDN, смотрим функцию GetTickCount
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx

И там же читаем
The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days. To avoid this problem, use the GetTickCount64 function. Otherwise, check for an overflow condition when comparing times.

Неужели это какой-то бином Ньютона? Не говоря о том, что по идее, в автодополнении GetTickCount64 должна быть.


 
CRLF   (2012-03-14 18:02) [33]


> Jeer ©   (14.03.12 17:35) [28]
Чего придираешься... Бухать устал.


 
Jeer ©   (2012-03-14 18:13) [34]


> Бухать устал.


Да.. не дошло до меня :)


 
pasha_golub ©   (2012-03-14 18:24) [35]


function GetTickCount: LongWord;
{$IFDEF DELPHI_12}inline;{$ENDIF}
begin
{$IFDEF MACOS}
 Result := AbsoluteToNanoseconds(UpTime) div 1000000;
{$ENDIF}
{$IFDEF MSWINDOWS}
 Result := Windows.GetTickCount;
{$ENDIF}
end;

function GetTickDiff(const AOldTickCount, ANewTickCount: LongWord): LongWord;
{$IFDEF DELPHI_12}inline;{$ENDIF}
begin
 {This is just in case the TickCount rolled back to zero}
 if ANewTickCount >= AOldTickCount then begin
   Result := ANewTickCount - AOldTickCount;
 end else begin
   Result := High(LongWord) - AOldTickCount + ANewTickCount;
 end;
end;

Привет Землянам!


 
pasha_golub ©   (2012-03-14 18:26) [36]

DELPHI_12 - это Д2009, он же Tiburon, если че


 
Sha ©   (2012-03-14 19:13) [37]

> Unknown user ©   (14.03.12 17:19) [23]

Ты задачу озвучь полностью, чего добиться хочешь?
А то, просто не верится, что такое бывает в реале.

> pasha_golub ©   (14.03.12 18:24) [35]

Привет братьям по разуму!
Веселье продолжается. Пил то же бухло?


 
antonn ©   (2012-03-14 22:32) [38]


> DVM ©   (14.03.12 00:27) [20]
>
>
> > в отдельном потоке и не завязаный на оконные сообщения
>
> там WaitableTimer + WaitForXXXObjects самое оно.

для чего? сабж возвращает время прошедшее со старта системы, а предложенное?


> Sha ©   (14.03.12 00:49) [22]
>
> > antonn ©   (14.03.12 00:18) [18]
>
> повеселили ребята
>

всегда рады


 
antonn ©   (2012-03-14 22:37) [39]


> Mystic ©   (14.03.12 17:58) [32]
>
> Идем в MSDN, смотрим функцию GetTickCount
> http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.
> 85).aspx

Requirements
Minimum supported client: Windows Vista
Minimum supported server: Windows Server 2008


 
DVM ©   (2012-03-14 23:03) [40]


> antonn ©   (14.03.12 22:32) [38]


> для чего? сабж возвращает время прошедшее со старта системы,
>  а предложенное?

сабж может и возвращает, но сабж применяется для организации ожидания в паре с циклом и просыпаниями через определенные интервалы времени.

WaitableTimer позволяет выставить таймер с любым интервалом, хоть 100 лет. WaitForXXX позволяют ждать срабатывания таймера хоть вечно + параллельно ждать сколько угодно событий таких как завершение потока и т.д. Крутить циклы со всякими GetTickCount, Sleep и т.д. расточительно и не правильно.



Страницы: 1 2 3 вся ветка

Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.075 c
15-1347692007
Roman_man
2012-09-15 10:53
2013.03.22
Как называется такой вид программы?


2-1331808385
Login2
2012-03-15 14:46
2013.03.22
Графический интерфейс


15-1353253627
alexdn
2012-11-18 19:47
2013.03.22
Совершенно дурацкий вопрос


15-1347788277
Pavia
2012-09-16 13:37
2013.03.22
Посоветуйте СУБД


15-1329061277
Бумбурум
2012-02-12 19:41
2013.03.22
нужен список ключ-значение.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский