Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Programm hängt trotz Indy Antifreeze und Threadauslagerung (https://www.delphipraxis.net/172131-programm-haengt-trotz-indy-antifreeze-und-threadauslagerung.html)

amigage 14. Dez 2012 14:06


Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Hallo liebe Delphi-Gemeinde,

ich hoffe, ihr könnt mir bei meinem spezifischen Problem helfen. Ich habe mich auch schon im Forum belesen,
leider habe ich keine Lösung finden können, die mein Problem löst.

Einfach gesagt, habe ich eine Form mit einem Ausgabe- und einem Eingabefeld.

Wenn die Form angezeigt wird, wird in der Prozedur
Delphi-Quellcode:
 procedure AfterFormShow(var Msg: TMessage); message WM_AFTER_SHOW;
der Cursor in das Eingabefeld gestellt und im Hintergrund in einem Thread eine HTTP-Abfrage duchgeführt.
Leider hängt das Programm trotz Auslagerung in einen Thread, weil die Indy-Komponente blockt.
Während auf die Antwort von FHTTP.get() gwartet wird, kann ich nicht sehen, was ich in das Eingabefeld eingebe. Das Fenster wird nicht aktualisiert.

Erst nach Ende der HTTP-Abfrage geht es. Selbst die globale Variable GAntiFreeze hilft mir nicht weiter.

Delphi-Quellcode:
type

  TMyThread = class(TThread)
  private
    TtmpKey  : String;
    TtmpSecret: String;

    procedure ThisIsMyFunction;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean);
  end;

 

{ TMyThread }

constructor TMyThread.Create(CreateSuspended: Boolean);
begin
  inherited;
end;

procedure TMyThread.ThisIsMyFunction;
  result_str : String;
begin
// ...

        result_str := GetFileInfo('', true);
// ...
end;

procedure TMyThread.Execute;
begin
  Synchronize(ThisIsMyFunction);
end;

....

Delphi-Quellcode:
procedure TMainDlg.AfterFormShow(var Msg: TMessage);
var
    DBThread: TMyThread;
begin
  editInput.Setfocus;
  Application.Processmessages;

  DBThread := TMyThread.Create(true);
  try
    DBThread.FreeOnTerminate := True;
    DBThread.Resume;
  except
  end;
 
end;
 

function TMainDlg.GetFileInfo(RemotePath: string; allFiles: boolean = false): String;
var
  listAllFiles : String;
  HTTPURL : String;
const
  FRoot = ''http://www.meinewebseite.de/';
begin
    If GAntiFreeze = NIL then
       GAntiFreeze.Create(nil);
     try
      GAntiFreeze.Active := true;

      HTTPURL := Format(url_metadata, [FRoot, URLEncodeRemotePath(RemotePath)]);
      try
        Result := FHTTP.Get(HTTPURL + '?' + OAuthRequest.GetString);
      except
         on E: EIdSocketError do
            begin
              Result := HTTPURL + SLineBreak + E.Message;
            end;
         on E: EIdHTTPProtocolException do
            begin
              Result := E.ErrorMessage;
            end;
      end;
    finally
      FHTTP.Disconnect;
      if Assigned(FHTTP.IOHandler) then FHTTP.IOHandler.InputBuffer.Clear;
      If Assigned(GAntiFreeze) then FreeAndNil(GAntiFreeze);
    end;

end;

Hätte noch jemand einen Tipp? Habe ich den separaten Thread falsch aufgebaut?

Danke für jede Hilfe.

Klaus01 14. Dez 2012 14:10

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  Synchronize(ThisIsMyFunction);
end;
versuche mal:

Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  Synchronize(ThisIsMyFunction);
  sleep(100);
end;
Grüße
Klaus

sirius 14. Dez 2012 14:24

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Es bringt nichts einen Thread anzulegen, und dort nur synchronize aufzurufen. Das ist wie ohne Thread zu arbeiten. (Wie kommt man eigentlich immer auf diese besch*** Idee? )

Blup 14. Dez 2012 14:35

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Dein Thread wartet lediglich darauf das der Hauptthread "ThisIsMyFunktion" abarbeitet.
Das hilft dir nicht weiter. Der Hauptthread arbeitet oder wartet innerhalb von "ThisIsMyFunktion" und die Oberfläche reagiert nicht mehr.

Die Variable GAntiFreeze nicht manuell ändern, verwende statt dessen die Komponente "TIdAntiFreeze".

jaenicke 14. Dez 2012 15:18

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Zitat:

Delphi-Quellcode:
    If GAntiFreeze = NIL then
       GAntiFreeze.Create(nil);

Wie erzeugt man nochmal ein Objekt? :shock:
Du musst das Objekt erzeugen und in die Variable legen und nicht die Methode Create des (da nil) nicht existierenden Objekts aufrufen und das (theoretisch) neue Objekt nicht speichern...

Zum Problem an sich wurde ja schon genug geschrieben...

amigage 17. Dez 2012 10:18

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
@sirius + @Blup:
besten Dank, jetzt funktionierts. Eure Aussagen haben mir die Augen geöffnet. Ehrlich gesagt ist es für mich das erste Mal, dass ich mit Threads hantiere. Auch wenn es nur ein simpler Thread ist.

Synchronize(Fktsname) also erst dann aufrufen, wenn der Thread die Arbeit beendet hat, um wieder Zugriff auf den Hauptthread zu bekommen. In meinem Fall die Freigabe von Schaltflächen.

Codehunter 17. Dez 2012 15:26

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Kleine Bitte am Rande: Seid doch nicht immer so unfreundlich wenn es um das Thema Threads geht. Manchmal hab ich den Eindruck, Threads wären die letzte Bastion elitärer Programmierkunst in der Delphiwelt, welches es bis aufs Messer zu verteidigen gilt.

Sir Rufo 17. Dez 2012 15:36

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Zitat:

Zitat von amigage (Beitrag 1195748)
@sirius + @Blup:
besten Dank, jetzt funktionierts. Eure Aussagen haben mir die Augen geöffnet. Ehrlich gesagt ist es für mich das erste Mal, dass ich mit Threads hantiere. Auch wenn es nur ein simpler Thread ist.

Synchronize(Fktsname) also erst dann aufrufen, wenn der Thread die Arbeit beendet hat, um wieder Zugriff auf den Hauptthread zu bekommen. In meinem Fall die Freigabe von Schaltflächen.

Delphi-Quellcode:
Synchronize
wird nur dann benötigt, wenn man aus einem Thread auf den Hauptthread zugreifen will. (Egal wann). Der Thread beendet sich auch so.

Wenn der Thread sich beendet, dann ruft der das Event
Delphi-Quellcode:
OnTerminate
auf.
Somit kann das Freischalten der Buttons oder whatever, was halt beim Beenden des Threads gemacht werden soll, damit aufgerufen werden.

CCRDude 18. Dez 2012 11:51

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
Zitat:

Zitat von Sir Rufo (Beitrag 1195784)
Delphi-Quellcode:
Synchronize
wird nur dann benötigt, wenn man aus einem Thread auf den Hauptthread zugreifen will. (Egal wann). Der Thread beendet sich auch so.

Nicht ganz richtig:

1. Der Austausch von Daten sollte mit allen anderen Threads sicher gestaltet werden, nicht nur der mit dem Hauptthread. TThread.Synchronize arbeitet lediglich mit/über diesen.

2. Benötigt nur solange, wie man keine anderen Methoden zur Thread-Absicherung verwendet (critical sections, TMultiReadExclusiveWriteSynchronizer o.ä.), aber dazu kommt man später im Umgang mit Threads, Punkt 1 war mir nur wichtig :)

bernhard_LA 18. Dez 2012 12:30

AW: Programm hängt trotz Indy Antifreeze und Threadauslagerung
 
ich hatte ähnlich Probleme beim Arbeiten mit TIdTCPserver.

Die Lösung waren bei mir : TIdSyncronize and TIdNotfy
Threads sind leider auch nicht meine starke Seite und es hat ziemlich lange gedauert bis ich diese Funktionen richtig angewandt habe.

Auf Stackoverflow habe ich hierzu sehr hilfreiche Beispiele gefunden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz