Application.ProcessMessages hanging?

my single-threaded delphi 2009 application (not quite finished yet) began to experience problems with Application.ProcessMessages hanging. my application has a TTimer object that runs every 100 ms to poll an external device. I use Application.ProcessMessages to refresh the screen when something changes, so the application is still responding.

one of them was in the OnMouseDown event of the grid. there, he had Application.ProcessMessages, which essentially hung. deleting was not a problem, except that I soon discovered another Application.ProcessMessages, which also blocked.

I think what can happen to me is that TTimer - in the application mode that I am currently debugging - is probably too long to complete. I prevented the TTimer.OnTimer event handler from re-entering the same code (see below):

procedure TfrmMeas.tmrCheckTimer(Sender: TObject);
begin
  if m_CheckTimerBusy then
    exit;

  m_CheckTimerBusy:=true;
  try
    PollForAndShowMeasurements;
  finally
    m_CheckTimerBusy:=false;
  end;
end;

In what places would it be bad practice to call Application.ProcessMessages? OnPaint routines come to mind as something that doesn't make sense.

any general recommendations?

I am surprised to see that this problem occurs at this stage of development!

+3
source share
5 answers

Thank you all for your comments / suggestions.

, , , . 1, Application.ProcessMessages . .

" " .

! .

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    Memo1: TMemo;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.Lines.Add('text 1');

  // this call blocks
  Application.ProcessMessages;

  memo1.Lines.Add('text 2');
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  iTime:cardinal;
begin
  // fix by adding this:  timer1.Enabled:=false;

  iTime:=GetTickCount;
  while GetTickCount-iTime<200 do
    ;

  // fix by adding this:  timer1.Enabled:=true;
end;

end.

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 286
  ClientWidth = 426
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 8
    Top = 56
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 112
    Top = 8
    Width = 297
    Height = 233
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
  object Timer1: TTimer
    Interval = 100
    OnTimer = Timer1Timer
    Left = 200
    Top = 144
  end
+2

TApplication.ProcessMessages , - .

, : , Windows ( , , ..), , , , , , , - " "... - . , .

(, ), , , .

- , , TWinControl.Repaint GUI.
, , backgroud/worker.

: Delphi , , CheckSynchronize, - ( , ) .
VCL , WM_NULL ( , , ).

+5

: " ? ";)

+1

madExcept, , .

+1

, , , , , .

:

  • . .
  • .
  • , , Application.ProcessMessages.

, 100 , :

09:00:00.000 - timer event fires
09:00:00.100 - we are half way through our Timer Event code. We hit an Application.ProcessMessages.
09:00:00.101 - timer event fires again, but the first time into it, has not yet completed.
09:00:00.200 - we are half way through our timer event code, the second time,
and hit APplication.ProcessMessages again.

... ... .....

0

Source: https://habr.com/ru/post/1749689/


All Articles