Советы по Delphi


Как осуществить задержку, не используя 100% времени CPU?


Я хочу создать серверное приложение (текстовый режим) в Delphi 3pro, ожидающее некоторые данные из последовательного порта. Во время ожидания мне необходимо "усыплять" приложение, дабы дать возможность другим программам полноценно использовать время CPU (простое зацикливание repeat ... until не подходит).

  1. repeat ... until не заблокирует другие процессы вашей системы из-за упреждающей мультизадачности win32, но вы правы - вы загрузите CPU на 100%. В этом случае вы заблокируете текущий процесс, означающий, к примеру, что в текущем приложении не будет происходить перерисовка окна.

  • вы можете обрабатывать приходящие сообщения в теле вашего цикла, чтобы решить проблемы перерисовки приложения, но загрузка CPU так и останется на уровне 100%. Сделать это можно примерно так:
  •     repeat
    while
    PeekMessage(Msg,0,0,0,pm_Remove) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; until ThereIsSomethingGoingOnOnTheSerialLine;

  • также вы можете использовать паузу (например, Sleep(100)) перед каждым опросом последовательного порта. Это значительно уменьшает нагрузку на CPU.
  • я не знаю каким способом вы получаете информацию от последовательного порта при наличии каких-то данных, но если ваш компонент или какой-то объект посылает вам системное сообщение при наличии необходимой информации, то наилучший способ решения проблемы - создание обработчика события при получении данного сообщения, который выполняет необходимые вам действия, но, поскольку вы в консольном режиме, вам понадобиться написать оконную функцию и установить ее консольному окну, например так:
  •     function MyWndProc(Wnd: HWnd; Msg,wParam,lParam:Integer): Integer;
    begin
    case
    Msg of wm_SerialLineReceivesData: begin ... end; else Result:=CallWindowProc(OldWndProc,Wnd,Msg,wParam,lParam); end; end;

    и в вашей главной программе:

        var
    OldWndProc: Pointer; begin

    OldWndProc:=
    Pointer(SetWindowLong(GetActiveWindow,gwl_WndProc, Integer(@MyWndProc))); ... SetWindowLong(GetActiveWindow,gwl_WndProc, Integer(OldWndProc)); end.

    [000263]




    Начало  Назад  Вперед