Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TThread, irgendwas mache ich falsch (https://www.delphipraxis.net/196215-tthread-irgendwas-mache-ich-falsch.html)

KodeZwerg 2. Mai 2018 16:14

AW: TThread, irgendwas mache ich falsch
 
Danke NG, jetzt hab ich verstanden was Du mit der Zeit meintest und Erfolgreich umgesetzt.
Falls es jemand Interessiert, hier die Lösung für mein Problem
Delphi-Quellcode:
function TFormMain.GetTHTTPClient ( Const xURL : String ) : String;
var
 tmp : String;
 MyThread: TThread;
begin
  tmp := '';
  MyThread := TThread.CreateAnonymousThread(
    procedure
    var
     HttpClient: THttpClient;
     HttpResponse: IHttpResponse;
    begin
      tmp := '';
      HttpClient := THTTPClient.Create;
      try
        HttpResponse := HttpClient.Get( xURL );
        tmp := HttpResponse.ContentAsString();
      finally
        HttpClient.Free;
      end;
    end
  );
  MyThread.FreeOnTerminate := True;
  MyThread.Start;
  repeat
    Application.ProcessMessages;
    Sleep(5);
  until WaitForSingleObject(MyThread.Handle, 5) = WAIT_FAILED;
  Result := tmp;
end;
Das Programm kann man weiterhin bedienen, nichts friert ein.
Danke für alle Hinweise und Tipps!

himitsu 2. Mai 2018 21:01

AW: TThread, irgendwas mache ich falsch
 
Delphi-Quellcode:
Sleep(5);
  until WaitForSingleObject(MyThread.Handle, 5)
Ein paar Dinge verstehen könntest du dennoch lernen :zwinker:

Sleep(5)_ohneEventbehandlung + WaitFor(5)_mitEventbehandlung = WaitFor(10)_undAllesMitEventbehandlung

Oder noch besser das WaitFor nicht nur auf dein Event, sondern auch auf die Warteschlange des VCL-Threads warten lassen.
> Delphi-Referenz durchsuchenDelay etwas anpassen

Whookie 3. Mai 2018 06:32

AW: TThread, irgendwas mache ich falsch
 
Man kann das natürlich so lösen, aber meist führt das zu weiteren Problemen (z.B. kann der Anwender das Programm nicht mehr beenden während es in einer solchen Schleife "festhängt").

Schleifen in denen Sleep und ProcessMessages verwendet werden sollte man aus meiner Sicht meiden, wenn ein Vorgang in Summe länger dauert dann gehört der ganze Vorgang in den Thread nicht nur Teile davon.

Klar bedeutet das in der Regel einen gewissen Umbauaufwand aber in den meisten Fällen hat man einfach nur "zu kurz" gedacht.

himitsu 3. Mai 2018 10:06

AW: TThread, irgendwas mache ich falsch
 
Application.Terminated in die Abbruchbedingung sollte halt mit rein, dann läßt es sich beenden, genau so, wie man es auch bei Threads mit Self.Terminated macht.

KodeZwerg 3. Mai 2018 10:16

AW: TThread, irgendwas mache ich falsch
 
Delphi-Quellcode:
  MyThread.FreeOnTerminate := True;
  MyThread.Start;
  repeat
    Application.ProcessMessages;
    Sleep(5);
    if CancelThread then
    begin
      ButtonDownload.Enabled := True;
      ButtonSaveOriginal.Enabled := False;
      ButtonCancelDownload.Enabled := False;
      CancelThread := False;
      tmp := 'Download aborted.';
      MyThread.Terminate;
    end;
  until WaitForSingleObject(MyThread.Handle, 5) = STATUS_PENDING;
So sieht es aktuell aus, Abbruch-Bedingung ist ein Globales Boolean, gesteuert über Knopf.
Momentan klappt allerdings irgendwie gar nichts so richtig.
Das mit den Sleep(5) ist irgendwie ein Automatismus bei mir, sobald ich ProcessMessages aufrufe.

Neutral General 3. Mai 2018 12:04

AW: TThread, irgendwas mache ich falsch
 
Musst du denn wirklich auf den Thread warten?
Reicht ein Callback aus dem Thread oder ein OnTerminated nicht in dem du deine Buttons etc wieder enablest/disablest?

Selbst wenn es so wie du es grade machst irgendwann funktionieren sollte wie du willst ist es trotzdem nichts von dem man behaupten kann, dass dort Threads sinnvoll eingesetzt werden. Oder anders gesagt: Wenn man auf einen Thread warten muss, dann stellt sich zumindest die Frage ob ein Thread in dem Fall eine gute Idee ist.
(Meistens nicht, manchmal vllt doch).

KodeZwerg 3. Mai 2018 13:00

AW: TThread, irgendwas mache ich falsch
 
@NG: Um ehrlich zu sein, ich weiß nicht ob ein Thread das Richtige Mittel ist.
Es nur eine Idee die ich mal ausprobieren wollte um an dieses Ziel zu gelangen:
Behebe bei App "keine Rückmeldung" und biete Option an den Download abzubrechen.
Mal klappt es mal nicht, ich spiele zu viel mit der until Bedingung rum.
Wenn ich wieder die kombination drinnen habe die funktioniert, also das ich entweder was downloade und wenn thread beendet ist es mir auch angezeigt wird, dann klappt es mit der "Download aborted." Nachricht nicht. Thread ist dann zwar abgebrochen aber ohne Nachricht ist es auch doof. Naja ich bastel da noch ein wenig herum.
Ohne Extra-Thread fehlt mir die Möglichkeit den Download abzubrechen und App friert ein solange Download am machen ist.

Edelfix 3. Mai 2018 13:43

AW: TThread, irgendwas mache ich falsch
 
Sollte eigentlich so funktionieren.
Delphi-Quellcode:
function TMainForm.GetTHTTPClient ( Const xURL : String ) : String;
var
 tmp : String;
 MyThread: TThread;
 TimeOut: Cardinal;
begin
  tmp := '';
  MyThread := TThread.CreateAnonymousThread(
    procedure
    var
     HttpClient: THttpClient;
     HttpResponse: IHttpResponse;
    begin
      tmp := '';
      HttpClient := THTTPClient.Create;
      try
        HttpResponse := HttpClient.Get( xURL );
        tmp := HttpResponse.ContentAsString();
      finally
        HttpClient.Free;
      end;
    end
  );
  MyThread.FreeOnTerminate := True;
  TimeOut := GetTickCount;
  MyThread.Start;
  repeat
    Application.ProcessMessages;
    Sleep(5);
  until (tmp<>'') or ((GetTickCount-TimeOut)>5000); //neu
  Result := tmp;
end;

KodeZwerg 3. Mai 2018 15:09

AW: TThread, irgendwas mache ich falsch
 
Delphi-Quellcode:
  until ((tmp <> '') or (WaitForSingleObject(MyThread.Handle, 5) = WAIT_FAILED));
Das ist die Lösung, auf den String zu achten, super Idee Edelfix. Danke! Nun klappt es exakt so wie ich es wollte, ich kann abbrechen, ich bekomme 'Download aborted.' und Thread schließt sich bzw bei Nicht-Abbruch bekomme ich auch das Ergebnis :thumb::thumb:

edit
Falls jemand mal brauchen sollte, so sieht eine Funktion aus die einen Thread startet und wartet bis der fertig ist um aus dem Thread einen String als Funktion = Result zu überreichen. Eine Abbruch-Funktion ist per Boolean CancelThread integriert.
Delphi-Quellcode:
function TFormMain.GetTHTTPClient ( Const xURL : String ) : String;
var
 tmp : String;
 MyThread: TThread;
begin
  tmp := '';
  CancelThread := False;
  MyThread := TThread.CreateAnonymousThread(
    procedure
    var
     HttpClient: THttpClient;
     HttpResponse: IHttpResponse;
    begin
      HttpClient := THTTPClient.Create;
      try
        HttpResponse := HttpClient.Get( xURL );
        tmp := HttpResponse.ContentAsString();
      finally
        HttpClient.Free;
      end;
    end
  );
  MyThread.FreeOnTerminate := True;
  MyThread.Start;
  repeat
    Application.ProcessMessages;
    Sleep(5);
    if CancelThread then
    begin
      ButtonDownload.Enabled := True;
      ButtonSaveOriginal.Enabled := False;
      ButtonCancelDownload.Enabled := False;
      CancelThread := False;
      tmp := 'Download aborted.';
      MyThread.Terminate;
    end;
  until ((tmp <> '') or (WaitForSingleObject(MyThread.Handle, 5) = WAIT_FAILED));
  Result := tmp;
end;
Durch die Art der Abfrage in der Repeat-Schleife sollte meines Wissens alles glatt laufen, entweder es existiert ein String oder Thread hat sich geschlossen.
Was haltet Ihr davon?

Stevie 3. Mai 2018 15:17

AW: TThread, irgendwas mache ich falsch
 
Bitte niemals auf das Handle eines Threads mit
Delphi-Quellcode:
FreeOnTerminate := True
warten!
An der Stelle, wo das Warten passiert, kann der Thread schon durchgelaufen und weg sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:36 Uhr.
Seite 3 von 5     123 45      

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