Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 01.05.2018, 16:54
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 280
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию Sleep В потоке + Log'гирование

Сам слип:
Код:
procedure WaitMe(msc: Cardinal);
var
  Ret: Dword;
  WaitTime: TLargeInteger;
  Timer: THandle;
begin
  // sleep  without freezing
  Timer := CreateWaitableTimer(nil, True, nil);
  WaitTime := -msc * 10000; 
  SetWaitableTimer(Timer, WaitTime, 0, nil, nil, false);
  repeat
    // (WAIT_OBJECT_0+0) is returned when the timer is signaled.           tw
    // (WAIT_OBJECT_0+1) is returned when a message is in the queue.
    Ret := MsgWaitForMultipleObjects(1, Timer, false, INFINITE, QS_ALLINPUT);
    if Ret <> (WAIT_OBJECT_0 + 1) then
      Break;
    Application.ProcessMessages;
  until false;
  if Ret <> WAIT_OBJECT_0 then
    CancelWaitableTimer(Timer);
  CloseHandle(Timer);
end;
Логирование
Код:
procedure TThr.AddLogEvent(Value: string; AColor: TColor);
var
  sTime: string;
begin

  try
    if fState then
      Synchronize(
        procedure
        begin
          sTime := '[' + FormatDateTime('hh:mm:ss:zzz', Now) + '] ';
          if AColor <> clBlack then
          begin
            MF.rLog.SelAttributes.Style := [fsBold];
            MF.rLog.SelAttributes.Color := AColor;
          end
          else
          begin
            MF.rLog.SelAttributes.Style := [];
            MF.rLog.SelAttributes.Color := clBlack;
          end;

          MF.rLog.lines.Add(sTime + Value);
        end);
  finally

  end;

end;
Примерный вызов:
Код:
procedure TThr.proc(...);
var
  ...
begin

  if t.Ntry > 0 then
  begin
    AddLogEvent(Format('Start Tick (RE_TRY) (%d) try #%d', [NextTryAfter, t.Ntry]), clWebDarkRed);
    WaitMe(NextTryAfter);
    AddLogEvent(Format('End Tick (RE_TRY) (%d) try #%d', [NextTryAfter, t.Ntry]), clWebDarkRed);
    if not NeedChange(t) then
    begin
....
      Exit
    end;
  end;
в итоге в логе мы видим
Цитата:
............
[22:58:52:515] Start Tick (RE_TRY) (1500) try #1
[Нужный слип в 1.5 сек]
[22:58:54:016] End Tick (RE_TRY) (1500) try #1
..........
[22:58:54:964] Start Tick (RE_TRY) (1500) try #2
опять все ок, слип прошел
[22:58:56:465] End Tick (RE_TRY) (1500) try #2
..........
[22:58:56:920] Start Tick (RE_TRY) (1500) try #3
И тут
[22:58:58:422] End Tick (RE_TRY) (1500) try #3
.........
[22:58:59:371] Start Tick (RE_TRY) (1500) try #4
По времени нету паузы
[22:59:00:872] End Tick (RE_TRY) (1500) try #4
Скорее всего это проблемы Синхронизации записи в лог? что можно сделать?
Ответить с цитированием
  #2  
Старый 01.05.2018, 20:06
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 663
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

А для чего Вам в потоке MsgWaitForMultipleObjects? У Вас используются окна в потоке? Вы отправляете в поток сообщения? Чем Вас не устроил простой Sleep() или SleepEx()?
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
  #3  
Старый 01.05.2018, 21:29
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 280
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

В первых вариантах был слип, но он мне фризил интерфейс основной формы, этот вариант мне помог. Потом, я нашел причину фризов, а возвращать слип как-то не стал. Это может быть как-то связано с проблемой?
Ответить с цитированием
  #4  
Старый 02.05.2018, 07:13
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 663
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Цитата:
Сообщение от nixon232
В первых вариантах был слип, но он мне фризил интерфейс основной формы, этот вариант мне помог.
Если дополнительный поток вызывает подвисание основного, значит что-то Вы делаете неверно. А именно программа не попадает в цикл обработки сообщений. Что Вы решили добавлением Application.ProcessMessage. Т.е. деления на потоки у Вас и не получилось.

Цитата:
Сообщение от nixon232
Потом, я нашел причину фризов, а возвращать слип как-то не стал. Это может быть как-то связано с проблемой?
Сложно сказать. Поставьте брейк и посмотрите откуда ноги растут. Хотя если бы мне нужна была пауза в потоке, и ничего кроме неё, Sleep вполне оправдан (это позволяет притормозить вызвавший поток и дать время на отработку остальных, что и должно предотвращать зависание).

Как итог, по Вашему куску кода можно сказать, что вся процедура WaitMe легко заменяется на Sleep. Ну а если пауза значительная и может повлиять на завершение программы (например пауза в 10 секунд не даст завершиться программе, пока доп поток не отработает), то можно сделать как мы с Вами обсуждали в прошлой теме - WaitForMultiplyObjects и ожидать либо таймер, либо событие завершения потока.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение:
nixon232 (02.05.2018)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 06:47.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025