Einzelnen Beitrag anzeigen

blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

Anwendung wird durch Herunterfahren abgewürgt...

  Alt 17. Apr 2008, 15:59
Hallo.

Nachdem ich nun seit 1 Woche an dem Problem hänge, frage ich mal hier nach.

Es geht um folgendes: Mein Programm bekommt beim Herunterfahren nicht die Möglichkeit zum Speichern.

Es sei folgender Thread gegeben;

Delphi-Quellcode:
type
   TMyThread = class(TThread)
     private
        Abbrechen: boolean;
        Fertig: boolean;
     protected
        procedure Execute; override;
     public
        function MyHalt: boolean;
        constructor create; virtual;
   end;
   
constructor TMyThread.create;
begin
  inherited create(true);
  freeOnTerminate := true;
end;

procedure TMyThread.Execute;
begin
  fertig := false;
  repeat
    if Abbrechen then break; // Abbrechen ist ein Flag, der die Schleife zum Verlassen verleitet
    form2.Label1.Caption := inttostr(strtoint(form2.Label1.Caption)+1);
  until false;
  sleep(10000); // Symbolisiert einen langen Speichervorgang
  form2.label1.caption := 'Sauber beendet';
  sleep(10000);
  fertig := true; // Der Funktion "MyHalt" mitteilen, dass wir fertig sind!
end;

//nDelay-Millisekunden nix tun
procedure Schlafen(nDelay: Integer);
var
nStart : Integer;
begin
nStart := GetTickCount;
while integer(GetTickCount)-nStart < nDelay do begin
Application.ProcessMessages;
Sleep(0);
end;
end;

function TMyThread.MyHalt: boolean;
begin
  Abbrechen := true; // Die Funktion Execute soll ihre interne Endlosschleife nun verlassen und Speichern
  while not fertig do Schlafen(1000); // Warten, bis interne Schleife im Thread selbstständig beendet und alles abgespeichert
  result := true;
end;
Der Thread wird von einem Timer einmalig gestartet:

Delphi-Quellcode:
type
  TForm2 = class(TForm)
  {...}
  public
    thr: TMyThread;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
  timer1.Enabled := false;

  SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS);

  thr := TMyThread.create;
  thr.Resume;
end;
Beim Beenden des Programms wird der Thread angehalten. Er hat die Möglichkeit zu speichern und darf sich dabei Zeit lassen!

Delphi-Quellcode:
type
  TForm2 = class(TForm)
  {...}
  private
    procedure WMQueryEndSession (var Msg: TWMQueryEndSession); message WM_QueryEndSession;

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  thr.MyHalt;
end;

// Auch bereits mit nur EndSession probiert!
procedure TForm2.WMQueryEndSession
      (var Msg : TWMQueryEndSession) ;
begin
  thr.MyHalt;
  Msg.Result := 1 ;
end;
Das normale Schließen funktioniert wie erwartet. Es wird 20 Sekunden gewartet, die Meldung ist vorhanden und es wurde somit symbolisch abgespeichert.

Das Problem ist nun: Egal wie ich es mache - das Programm bekommt beim Herunterfahren nicht die Möglichkeit, "abzuspeichern". Normalerweiße sollte der Counter sofort nach dem Klick auf "Herunterfahren" anhalten (aufgrund des Setzens von "Abbrechen:=true" bei "MyHalt"). Dann sollte das Programm 10 Sekunden verweilen und dann "Sauber beendet" anzeigen, dann nocheinmal 10 Sekunden warten und dann erst sollte es schließen. Was ist hier falsch?
Ich habe es schon mit allen möglichen Variationen - mit und ohne Thread, mit nur EndSession oder nur QueryEndSession oder beides usw.
Kann mir jemand helfen?

Gruß
blackdrake

// Nachtrag: Das Problem war ein fehlerhaft gesetzter Regkey (ich glaube es war "AutoEndTasks"). Keine Ahnung, welches geniale "Tool" einen solch dummen Wert ohne meine Kenntnis verändert hat.
// http://www.addictivetips.com/windows...tdown-process/
Daniel Marschall
  Mit Zitat antworten Zitat