AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Form reagiert nicht während idftp1.get trotz application.processmessages
Thema durchsuchen
Ansicht
Themen-Optionen

Form reagiert nicht während idftp1.get trotz application.processmessages

Ein Thema von gee21 · begonnen am 12. Jul 2014 · letzter Beitrag vom 15. Jul 2014
Antwort Antwort
Seite 1 von 2  1 2      
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 14:27
Delphi-Quellcode:
procedure geetest.Execute;
begin
   NameThreadForDebugging('threadgee');
   { Place thread code here }

   form1.idftp1.get(filelistFINAL[i4],gethomepath+'/Temp/'+filelistFINAL[i4], true);
end;
Du darfst Form1.IdFtp1.Get() NICHT in deinem Thread aufrufen, weil du sonst die Funktion im Hauptthread der Anwendung aufrufst (TForm1 ) und diese dort auch ausgeführt wird. Das heisst dass dein Thread in dem Moment garkeinen Sinn mehr hat.

Was du in etwa machen musst:
Delphi-Quellcode:
unit threadtest;

interface

uses
  System.Classes, System.SysUtils,

  // Indy Units
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdExplicitTLSClientServerBase, IdFTP;

type
   TThreadTest = class(TThread)
     constructor Create(AFileListFinal: TStringList);
     destructor Destroy; override;
   protected
     FIdFtp: TIdFTP;
     FConnected: Boolean;
     FDownloading: Boolean;
     FFileList: TStringList;
     procedure Execute; override;

     procedure AfterGet(Sender: TObject; Stream: TStream);
     procedure Connected(Sender: TObject);
   public
   end;

implementation

function GetHomePath: String;
begin
  // Die Funktion darf ebenso KEINEN Zugriff auf Komponenten von Form1 oder sowas nehmen.
  Result := '/var/www/...';
end;

procedure TThreadTest.Execute;
var
  i4: Integer;
begin
   NameThreadForDebugging('threadgee');

   FConnected := FALSE;
   FDownloading := FALSE;
   i4 := 4;
   FIdFtp.Connect;

   while not Terminated do
     begin
       Sleep(1);
       if not FConnected then
         Continue;

       if not FDownloading then
         begin
           FDownloading := TRUE;
           Sleep(500);

           FIdFtp.Get(FFileList[i4], GetHomePath + '/Temp/' + FFileList[i4], TRUE);
         end;
     end;
end;

constructor TThreadTest.Create(AFileListFinal: TStringList);
begin
  FFileList := AFileListFinal;
  FIdFtp := TIdFTP.Create(nil);
  with FIdFtp do
    begin
      Host := '...';
      Username := 'lieschen';
      Password := 'purzel123';
      OnConnected := Connected;
      OnAfterGet := AfterGet;
    end;

  inherited Create(FALSE);
  FreeOnTerminate := TRUE;
end;

destructor TThreadTest.Destroy;
begin
  FIdFtp.Free;
end;

procedure TThreadTest.Connected(Sender: TObject);
begin
  FConnected := TRUE;
end;

procedure TThreadTest.AfterGet(Sender: TObject; Stream: TStream);
begin
  Sleep(500);
  FIdFtp.Disconnect;
  FConnected := FALSE;

  Terminate;
end;

end.
Aufruf in deiner Form1
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  TTestThread.Create(filelistFINAL);
end;
Ungetestet und ausm Kopf. Also kopier das jetzt nicht einfach 1:1 und sag dann "Es geht nicht!!!111". Da krieg ich schlechte Laune.

Es soll nur das Prinzip verdeutlichen. Das ist ungefähr das, was Sir Rufo mit "autark" meint. Dein Thread darf sich nicht (ohne weiteres) von Inhalten aus Form1 bedienen oder Funktionen darauf aufrufen.

Geändert von nuclearping (13. Jul 2014 um 15:31 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#2

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 14:52
Blöde Frage: Es ist korrekt, die FTP-Komponente im Hauptthread zu erzeugen (im Konstruktor), das 'Get' aber im Kontext des Threads aufzurufen? Ich würde die Komponente als lokale Variable im Execute erzeugen, verwenden und wieder freigeben (mit Try-Finally natürlich).
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 15:28
Blöde Frage: Es ist korrekt, die FTP-Komponente im Hauptthread zu erzeugen (im Konstruktor), das 'Get' aber im Kontext des Threads aufzurufen?
Das macht er ja. Und es funktioniert nicht.
  Mit Zitat antworten Zitat
gee21

Registriert seit: 3. Jan 2013
199 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 17:19
Hey Leute ihr seit super.

Ich glaube bei mir hat es zuerst nicht geklappt da ich nur die "idftp1.get" Zeile im Thread hatte und jetzt wo ich die ganze Schlaufe in den Thread genommen habe, läuft es perfekt und sehr sehr schnell.


Obwohl ich im Moment im Thread immer noch: Form1.idftp1.get... habe

form1.idftp1.get(filelistFINAL[i4],gethomepath+'/Temp/'+filelistFINAL[i4], true); Funktioniert aber so gut, das ich mich kaum getraue was zu ändern
Robert
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 17:32
Nun dann solltest du beten, dass du die Form niemals umbenennst und den Thread nur einmal erzeugst ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
gee21

Registriert seit: 3. Jan 2013
199 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 17:42
Nun dann solltest du beten, dass du die Form niemals umbenennst und den Thread nur einmal erzeugst ...
Ok, vielleicht ändere ich es dann doch noch lieber. Danke

Aber ich habe jetzt den Thread 3-4 mal im selben Programmstart aufgerufen und es klappt tiptop.
Robert
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 18:25
Nun dann solltest du beten, dass du die Form niemals umbenennst und den Thread nur einmal erzeugst ...
Ok, vielleicht ändere ich es dann doch noch lieber. Danke

Aber ich habe jetzt den Thread 3-4 mal im selben Programmstart aufgerufen und es klappt tiptop.
Dann erzeuge doch mal direkt 2 Instanzen von dem Thread und schau dir an, was dabei rauskommt.

Bzw. zeig doch mal den Code, wie du den Thread "aufrufst" ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.166 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 18:55
Du darfst Form1.IdFtp1.Get() NICHT in deinem Thread aufrufen, weil du sonst die Funktion im Hauptthread der Anwendung aufrufst (TForm1 ) und diese dort auch ausgeführt wird. Das heisst dass dein Thread in dem Moment garkeinen Sinn mehr hat.
Wie kommst Du den darauf?
  Mit Zitat antworten Zitat
gee21

Registriert seit: 3. Jan 2013
199 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 19:01
@SirRufo

So ruf ich ihn auf (in einem Button)
geetest.Create(False); Und das ist der komplette Thread

Delphi-Quellcode:
unit threadtest;

interface

uses
  System.Classes, f1diashow,f4einstellungendiashow, System.SysUtils;

type
  geetest = class(TThread)
  protected
    procedure Execute; override;
  end;


implementation


procedure vclsettings;
begin
                  form1.Image1.Visible:=true;
                  form1.Image1.Bitmap.LoadFromFile(playlist[0]);
                  form1.image1.Height:=form1.Height;
                  form1.image1.Width:=form1.Width;
                  form1.image1.Position.X:=0;
                  form1.image1.Position.Y:=0;
                  count:=0;
                  form1.speedbutton1.Visible:=false;
                  form1.speedbutton3.Visible:=false;
                  form1.listbox1.Visible:=false;
                  form1.Panel2.Visible:=false;
                  form1.Timer1.Enabled:=true;
                  form1.speedbutton2.Visible:=true;
                  form1.label3.Visible:=false;
                  form1.progressbar1.Value:=0;
end;



procedure geetest.Execute;
var
i4: integer;
begin
  NameThreadForDebugging('threadgee');
  { Place thread code here }


  if filelistFINAL.Count>form4.SpinBox2.Value-1 then form1.progressbar1.Max:=form4.SpinBox2.Value else form1.progressbar1.Max:= filelistFINAL.Count;

  for i4 := 0 to filelistFINAL.Count-1 do begin

          if stop=false then begin
          form1.progressbar1.value:=i4+1;

                  try
                  form1.idftp1.get(filelistFINAL[i4],gethomepath+'/Temp/'+filelistFINAL[i4], true);
                  except
                  end;

          PlayList.add(gethomepath+'/Temp/'+filelistFINAL[i4]);

          //Während des Downloads wird die DIASHOW gestartet (ja nach Puffer Grösse)
  if form1.Timer1.Enabled=false then begin

           if filelistfinal.Count>form4.SpinBox2.Value-1 then begin
                  //SOFERN playlist grösser ist als der Puffer
                  if PlayList.Count>form4.spinbox2.value-1 then begin
                  form1.progressbar1.value:=i4+1;
                  form1.timer1.interval:=strtoint(form4.SpinBox1.text)*1000;
                   Synchronize(vclsettings);
                  end;

               // ist die FileListFINAL kleiner als der Puffer und aber mindestens 1 Bild geladen
         end else if playlist.count>-1 then begin
                  form1.progressbar1.value:=i4+1;
                  form1.timer1.interval:=strtoint(form4.SpinBox1.text)*1000;
                  Synchronize(vclsettings);
                  end;


          end;
      end else begin
       //Schlaufe wir abgebrochen da Boolean STOP=TRUE ist
      form1.timer1.Enabled:=false;
      form1.image1.Bitmap:=nil;
      form1.speedbutton1.Visible:=true;
      form1.speedbutton3.Visible:=true;
      form1.listbox1.Visible:=true;
      form1.image1.Visible:=false;
      form1.label3.Visible:=true;
      form1.speedbutton2.Visible:=false;
      form1.panel2.Visible:=false;

       break;

      end;

end;

end;
end.







@ Mavarik:

Ja habe eben bis heute noch nie mit einem Thread gearbeitet. (Wie du wahrscheinlich sehr gut am meinem oben erkennen kannst).



@nuclearping

Irgendeinen Unterschied macht es schon. den so friert die form1 nicht mehr ein.
Robert
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Form reagiert nicht während idftp1.get trotz application.processmessages

  Alt 13. Jul 2014, 19:16
Ich weiß nicht wo ich da anfangen soll ... ok, da ist irgendwie alles falsch, was man falsch machen kann.
  • Exception-Handling
  • Zugriff über form1
  • Zugriff vom Thread-Kontext auf den MainThread-Kontext
  • if stop = false ist noch der harmloseste, warum nicht if not stop ?

Die Funktion kommt glücklicherweise zustande und unglücklicherweise tut da tatsächlich was, so dass du denkst, so kann man das ruhig machen.

Ein Tutorial zum Thema Threadding und Grundlagen zum Threadding allgemein wären dringend angebracht, wenn du ernsthaft mit Threads arbeiten möchtest. Das ist allerdings der Ritt auf Messers Schneide ohne Gurt.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz