[Delphi] Application.Processmessages; Грузит проц

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by xophet, 31 Aug 2011.

  1. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    Проблемка
    Code:
      repeat
        Application.ProcessMessages;
      until false;
    грузит проц на 100%,
    а раньше такого не было (если было, то я свой дом труба шатал!)
    никто не сталкивался с такой проблемой?
    P.S. новый проект, на клике кнопки висит код, приведенный выше.
     
  2. Wave

    Wave Member

    Joined:
    15 Aug 2010
    Messages:
    89
    Likes Received:
    11
    Reputations:
    0
    Цикл с Application.ProcessMessages мне кажется не очень удачным решением чего бы то ни было.

    чтобы не загружать процессор, добавь в цикл Sleep с небольшим числом.
     
    #2 Wave, 31 Aug 2011
    Last edited: 31 Aug 2011
  3. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    Sleep с небольшим числом не катит т.к. в процессе этого вот цикла мне нужно обрабатывать много сообщений форме (если ставлю слип(10) форма тупо повисает)

    ______________________
    за
    вроде бы как наказывают
     
  4. Wave

    Wave Member

    Joined:
    15 Aug 2010
    Messages:
    89
    Likes Received:
    11
    Reputations:
    0
    ага.. наказывают )
    тогда делай апдейт кампу... ставь проц которого так просто не загрузишь
    нагрузка на проц при Application.ProcessMessages; не только у тебя... он всегда грузить ЦП
     
  5. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Была такая же трабла, когда учился с OpenGL работать и окна с помощью WinAPI создавать. Вообще так делать нельзя, тут два варианта :
    1. Поставить Sleep(1); Тогда не будет тормозить, но это тоже не верно.
    2. Написать так :
    repeat
    Application.ProcessMessages;
    WaitMessage;
    until false;

    Тут грамотно, но если ты это делаешь синхронизированно с каким нить левым потоком - код встанет пока не придет любое сообщение, тут то как раз и первый вариант нужен.
     
    2 people like this.
  6. gavriil

    gavriil New Member

    Joined:
    18 Aug 2011
    Messages:
    11
    Likes Received:
    3
    Reputations:
    0
    В отдельный поток закидываешь обработку таких данных
    Там же sleep(10);

    В итоге и форма получает сообщения и поток обрабатывает данные не нагружая форму.
     
    2 people like this.
  7. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    Спасибо!

    Спасибо, если припрет, то так и сделаю.
     
  8. ImLucky

    ImLucky New Member

    Joined:
    26 Sep 2010
    Messages:
    72
    Likes Received:
    3
    Reputations:
    0
    Что ты везде со своими плюсами ?Сам попрашайничаешь так и других подбиваешь.

    Если человек сочтет нужным, то отправит и без чьих-то указаний.

    Сорри за оффтоп.
     
    1 person likes this.
  9. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Бред, обработку сообщений можно обрабатывать только в главном иначе если и не сразу, то потом будет карачун.
     
  10. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Может он имел в виду, что принимать сообщения нужно из главного потока, а делать обработку некоторых из них - в дополнительном.
     
  11. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    На сколько я понял он имел в виду, что действия требующие задержки делать в отдельном потоке, а обрабатывать сообщения - в главном.

    На счет потоков я не знаю, но читал (поправьте, если ошибаюсь), что сообщения форма пересылает всем созданным объектам.
    поток - объект.
    т.е. чисто теоретически должно и потоку пересылаться.
    делаем у него процедуру procedure che_to_tam(var message:tmessage); message:WM_chee_to_tut;
    и все сообщения с идентификатором WM_chee_to_tut; обрабатываются потоком
     
  12. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Не совсем, вызываться метод потока с сообщением WM_chee_to_tut будет в контексе потока в котором вызывается обработка сообщений(Application.ProcessMessages) в левом потоке как раз нельзя вызывать обработку сообщений, потому что будут затронуты данные без синхронизации принадлежащий главному потоку, тобешь форму к примеру.
     
  13. gavriil

    gavriil New Member

    Joined:
    18 Aug 2011
    Messages:
    11
    Likes Received:
    3
    Reputations:
    0
    Что мешает создать В ОТДЕЛЬНОМ потоке новое окно и на него принимать сообщения ?

    PHP:

    function PlainWinProc(hWndTHandlenMsgUINT;
      
    wParamlParamCardinal): Cardinal
    var
      
    RectTRect;
    begin
      Result 
    := 0;
      case 
    nMsg of
        wm_Create
    :
          
    sleep(1);
        
    wm_Command:
          
    sleep(1);
        
    wm_Destroy:
          
    sleep(1);
      else
        
    Result := DefWindowProc(hWndnMsgwParamlParam);
      
    end;
    end;

    procedure WinMain;
    var
      
    hWndTHandle;
      
    MsgTMsg;
      
    WndClassExTWndClassEx;
    begin
      
    // initialize the window class structure
      
    WndClassEx.cbSize := sizeOf(TWndClassEx);
      
    WndClassEx.lpszClassName := 'PlainWindow';
      
    WndClassEx.style := cs_VRedraw or cs_HRedraw;
      
    WndClassEx.hInstance := HInstance;
      
    WndClassEx.lpfnWndProc := @PlainWinProc;
      
    WndClassEx.cbClsExtra := 0;
      
    WndClassEx.cbWndExtra := 0;
      
    WndClassEx.hIcon := LoadIcon(hInstanceMakeIntResource('MAINICON'));
      
    WndClassEx.hIconSm := LoadIcon(hInstanceMakeIntResource('MAINICON'));
      
    WndClassEx.hCursor := LoadCursor(0idc_Arrow);
      ;
      
    WndClassEx.hbrBackground := GetStockObject(white_Brush);
      
    WndClassEx.lpszMenuName := nil;
      
    // register the class
      
    if RegisterClassEx(WndClassEx) <> 0 then
      begin
        hWnd 
    := CreateWindowEx(
          
    ws_Ex_OverlappedWindow// extended styles
          
    WndClassEx.lpszClassName// class name
          
    'Window'// title
          
    ws_OverlappedWindow// styles
          
    100100// position
          
    11// size
          
    0// parent window
          
    0// menu
          
    HInstance// instance handle
          
    nil); // initial parameters
        
    if hWnd <> 0 then
        begin
          ShowWindow
    (hWndsw_ShowNormal); // тут показ окна если не нужен закоментировать

            
    while GetMessage (Msg000) do
            
    begin
              TranslateMessage 
    (Msg);
              
    DispatchMessage (Msg);
            
    end;   

        
    end;
      
    end;
    end;

     
    #13 gavriil, 9 Sep 2011
    Last edited: 10 Sep 2011
  14. gavriil

    gavriil New Member

    Joined:
    18 Aug 2011
    Messages:
    11
    Likes Received:
    3
    Reputations:
    0
    > А копипастить всюду кусок говнокода

    Критикуя - предлагай!

    За наводку на AllocateHWnd спасибо, почитаю.
     
  15. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Толку...один фик обработка всегда в одном потоке обрабатывается. Нет разницы в каком потоке окно создаешь.

    P.S. AllocateHWnd не следует использовать если без VCL пишешь, т.к. это есть часть VCL, то есть потянет много чего не нужного, я просто писал аналог этой функции если уж на API писать.
     
  16. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Code:
    function AllocateHWnd(Method: TWndMethod): HWND;
    Функция из модуля Forms, я имел ввиду ее.