Wann ist eine Anwendung startbereit

Für Fragen von Einsteigern und Programmieranfängern...
siro
Beiträge: 469
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Wann ist eine Anwendung startbereit

Beitrag von siro »

Moin zusammen,

Gibt es ein Flag, Funktion, Event oder was auch immer, wo man weis, dass die Anwendung komplett initialisiert ist ?
Alle Formulare geladen sind, alle Construktoren durchlaufen wurden ?

Bestimmte Dinge dürfen erst abgearbeitet werden wenn die komplette Anwendung initialisiert ist.
Bei mir zum Beispiel habe ich einen Timer auf FormA und der sendet etwas auf die Schnittstelle RS232,
dann kommen Daten von der Schnittstelle und die werden an FormB gesendet.

Das Problem beim Starten:
Ich weis nicht wann ich etwas tätigen darf, wann ist denn FormB soweit dass es Daten empfangen kann ?.
Der Speicher für meine Messpuffer werden erst in FormB angelegt.
Ich weis auch nicht welche Reihenfolge durchlaufen wird, ist das immer in der Reihenfolge der Units.
Ehrlich gesagt möchte ich mich darum auch garnicht kümmern müssen.

Es gibt ja auch "Loaded" das habe ich auch schon überschrieben bei Komponenten, aber wann ist ALLES geloaded und wann wurden ALLE Construktoren
durchlaufen ?.

Ich habe auch oft in meinen Komponenten:
if (csDesigning in ComponentState) or (csLoading in ComponentState) then mache erstmal nix...

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
six1
Beiträge: 403
Registriert: Do 1. Jul 2010, 19:01

Re: Wann ist eine Anwendung startbereit

Beitrag von six1 »

Tja, ich war da auch immer unischer und habe selbst mit "onShow" nicht immer gute Erfahrungen gehabt.
Habe mir angewöhnt, einen Timer auf die Mainform zu legen, den nenne ich "StartTimer".
Im OnShow wird dieser Timer gestartet. Der Timer hat eine Verzögerung von 20 ms.
Damit hatte ich noch niemals Probleme, dass etwas noch nicht fertig erzeugt war.
Gruß, Michael

siro
Beiträge: 469
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Wann ist eine Anwendung startbereit

Beitrag von siro »

So ähnliche Ideen hatte ich auch schon,
Wenn die Anwendung aber etwas läd und das System auch grade was rumschrappelt, kann das Sekunden dauern...
und dann hat man wieder nichts gewonnen. Das ist natürlich keine schöne/saubere Lösung.
Ich hatte mir am Anfang aber auch mal so beholfen.
Zuletzt geändert von siro am So 16. Mai 2021, 09:12, insgesamt 2-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
six1
Beiträge: 403
Registriert: Do 1. Jul 2010, 19:01

Re: Wann ist eine Anwendung startbereit

Beitrag von six1 »

Wenn du derartige Eingangsbedingungen hast, würde ich flags setzen, wenn nötige Aufgaben erledigt sind und der "Spaß" losgehen kann.
Über den Starttimer kannst du prüfen, ob alle Flags deiner Bedingungen erfüllt sind.
Gruß, Michael

siro
Beiträge: 469
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Wann ist eine Anwendung startbereit

Beitrag von siro »

Grade eine Idee bekommem, wäre hier ein FLAG sinnvoll ??

Code: Alles auswählen

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  Application.CreateForm(TFormMain, Form_Main);
  Application.CreateForm(TFormBatterietest, FormBatterietest);
  Application.CreateForm(TFormCurves, Form_Curve);
               FReady:=TRUE;   // vermutlich müsse das der richtige Zeitpunkt sein ????
  Application.Run;
end.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
six1
Beiträge: 403
Registriert: Do 1. Jul 2010, 19:01

Re: Wann ist eine Anwendung startbereit

Beitrag von six1 »

:lol: zwei Dumme, ein Gedanke...
Gruß, Michael

siro
Beiträge: 469
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Wann ist eine Anwendung startbereit

Beitrag von siro »

Füge ich später ein Formular hinzu, steht mein Flag aber an falscher Stelle, habe ich grad ausprobiert:

Code: Alles auswählen

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  Application.CreateForm(TFormMain, Form_Main);
  Application.CreateForm(TFormBatterietest, FormBatterietest);
  Application.CreateForm(TFormCurves, Form_Curve);
    ReadyToRun:=TRUE;  // vermutlich müsse das der richtige Zeitpunkt sien ????
  Application.CreateForm(TForm1, Form1);     // Bäääh, nicht hier...
  Application.Run;
end.          
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Michl
Beiträge: 2424
Registriert: Di 19. Jun 2012, 12:54

Re: Wann ist eine Anwendung startbereit

Beitrag von Michl »

siro hat geschrieben:
So 16. Mai 2021, 08:59
Gibt es ein Flag, Funktion, Event oder was auch immer, wo man weis, dass die Anwendung komplett initialisiert ist ?
Alle Formulare geladen sind, alle Construktoren durchlaufen wurden ?
Einen Timer, besser TIdleTimer, kann man durchaus dafür nutzen. Wenn man aber nur einen Aufruf benötigt, geht z.B. auch Application.QueueAsyncCall. Alles wird erst bei Application.Idle aufgerufen (wenn der MainThread in den "Leerlauf schaltet" - alle Messages abgearbeitet sind).

z.B.:

Code: Alles auswählen

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    procedure Test(Data: PtrInt);
  end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.QueueAsyncCall(@Test, 0);
end;

procedure TForm1.Test(Data: PtrInt);
begin
  Caption := 'Gestartet';
end;  

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

siro
Beiträge: 469
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Wann ist eine Anwendung startbereit

Beitrag von siro »

Ersteinmal vielen Dank für die Infos an Michael und Michl.

Das muss ich mir jetzt mal genauer ansehen. IdleTimer klingt gut, den habe ich, glaube ich zumindest, auch verstanden.
Mit dem Asynchronous Call, hab ich noch nicht wirklich verstanden, werde aber auch damit mal etwas experimentieren.
Ich werde mir dafür ein spezielles Testprojekt erzeugen um das zu verfolgen.

Kann es eigentlich passieren, dass die Anwendung auch während des Startens kurz "IDLE" wird ?
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Michl
Beiträge: 2424
Registriert: Di 19. Jun 2012, 12:54

Re: Wann ist eine Anwendung startbereit

Beitrag von Michl »

siro hat geschrieben:
So 16. Mai 2021, 11:20
Kann es eigentlich passieren, dass die Anwendung auch während des Startens kurz "IDLE" wird ?
Mir ist kein Fall bekannt. Alle Messages zum Erstellen der Controls werden in die MessageQueue eingetragen und abgearbeitet, bevor die Anwendung Idle wird.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

wp_xyz
Beiträge: 3746
Registriert: Fr 8. Apr 2011, 09:01

Re: Wann ist eine Anwendung startbereit

Beitrag von wp_xyz »

Mein Standard-Vorgehen in dem Fall, dass die Initialisierung im OnCreate-Event des Hauptformulars zu früh kommt und OnActivate bzw. OnShow nicht geeignet sind (weil sie wiederholt aufgerufen werden können), ist eine Methode "BeforeRun" im Hauptformular, die ich in der Projekt-Datei - wie der Name sagt - vor Application.Run aufrufe und in der all die nötige Initialisierung steckt.

Code: Alles auswählen

type
  TForm1 = type(TForm)
  public
    procedure BeforeRun;
  end;
  
procedure TForm1.BeforeRun;
begin
  // Initialisierungs-Code
end;

-----------

program Project1;
....
begin
  ...
  Application.CreateForm(TForm1, Form1);
  ...
  Form1.BeforeRun;
  Application.Run;
 end.
Alternativ könnte man den Code auch in OnActivate oder OnShow stecken und die wiederholte Ausführung durch ein Flag "InitDone" unterbinden:

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
begin
  if not InitDone then
  begin
    ...  // Initialisierungscode
    InitDone := true;
  end;
end;

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wann ist eine Anwendung startbereit

Beitrag von Winni »

Hi!

FormActivate ist die richtige Stelle, bei der man davon ausgehen kann, dass alles von FromCreate abgearbeitet ist. Hier erhält die HauptForm auch den Focus. Unter Linux wird onActivate nur einmal ausgeführt. Für Windows gibt's diese Spezialbehandlung:

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
begin
      OnActivate:= nil;
end;
Weiterhin kann man eine globale variable setzen, die verhindert, dass Procedure ausgeführt werden, obwohl noch nicht alles initialisiert ist, wie z.B. FormPaint

Code: Alles auswählen

var startup: Boolean = true;
Solange startup noch true ist, steigt man z.B. aus FormPaint mit exit aus.
In FormActivate setzt man dann startup auf false und die Application kann laufen, wie gewünscht.

Winni

Michl
Beiträge: 2424
Registriert: Di 19. Jun 2012, 12:54

Re: Wann ist eine Anwendung startbereit

Beitrag von Michl »

Winni hat geschrieben:
So 16. Mai 2021, 12:12
FormActivate ist die richtige Stelle
Das kannst du nicht so allgemein sagen. Auch eine globalisierte Variable hilft nicht in allen Fällen.

Ich habe hier zum Beispiel eine große Datenbankanwendung, die nach dem Start eine allgemeine Übersichtstabelle zeigt. OnPaint wird nach OnActivate gefeuert und endet mit einem SIGSEGV, da die Daten noch nicht aus der Datenbank geholt wurden. Daher ist Application.OnIdle für mich der früheste Zeitpunkt die Anwendung als startbereit zu erklären. Noch interessanter ist es in einer anderen Anwendung. Diese lasse ich starten und mach sie "nutzbar". Zeitintensive Daten hole ich per Thread. Erst wenn diese alle da sind, ist die Anwendung wirklich initialisiert bzw. voll nutzbar. Wie gesagt, es kommt je nach Anwendungsfall darauf an.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wann ist eine Anwendung startbereit

Beitrag von Winni »

Hi!

Natürlich- wenn Du mit so langsamen Zeugs wie einerDB arbeitest, dann brauchst Du ne zweite boolsche Variable, die anzeigt ob die DB schon ready ist.

Außerdem würde ich nie automatisch Daten aus einer DB beim Programmstart anzeigen.
Dafür darf der User schon mal irgendwo hinklicken.

Winni

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4609
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Wann ist eine Anwendung startbereit

Beitrag von af0815 »

Ich verwende seit Jahren und nicht nur bei Lazarus immer OnActivate mit einem InitFlag.

Das ist seit Delphizeiten die Stelle, wo wirklich alle Komponenten erzeugt sind und beim Hauptformular (das ist auch wichtig !!) mit dem ersten Auftauchen des Formular zusammenhängt. Ich habe gelernt micht nicht auf die Reihenfolge der Events zu verlassen, schon nicht zu Delphis Zeiten. Zu diesem Zeitpunkt sind auch alle Datenmodule etc. bereits initialisiert und man kann auch hier Verbindungen öffnen, auch wenn RAD-DB Komponenten im Spiel sind. Auch die Liste der erzeugten Formulare und Datenmodule ist dann abgearbeitet, wobei natürlich das erste Formular das Hauptformular ist. Das muss man schon beachten, bzw. berücksichtigen, wenn man das ändert.
Generell habe ich mir angewöhnt nur ein (Haupt-) Formular zu haben und nur dieses erzeugt alles was es benötigt selbst. Damit werden auch lästige Sachen bei Lazarus, wenn man ein Projekt klont, wie das plötzlich Formulare aus der Liste der automatisch erzeugten Formulare verschwindet, nicht so tragisch. Das sieht man dann beim ersten Start, wenn überhaupt kein Formular erzeugt wird.

Mit der Methodik, habe ich duzende Programme im beruflichen Umfeld am Laufen, egal ob Win, Linux/X64 oder Raspian .

Zu den DB-Conntions, dort einen Autostart zu machen, ist eher was für Leute die auf Probleme stehen. Von mir aus, gehören die automatisch deaktiviert, wenn man nicht im RAD-Design ist. Wenn man die verwendet, dann maximal für eine ganz einfache 'Hello DB'. Das und ein 'SELECT * FROM' und ich sage - nicht genügend setzen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten