Thema: Delphi IdFTP + Threads

Einzelnen Beitrag anzeigen

naujo

Registriert seit: 31. Jan 2005
25 Beiträge
 
Delphi 6 Enterprise
 
#1

IdFTP + Threads

  Alt 30. Okt 2006, 14:54
Hallo zusammen!

Ich möchte unter Delphi 6 mit Indy 10 einen kleinen FTP-Client programmieren.

Das "Grundgerüst" mit der Finktionalität steht schon. Nun habe ich ein paar kleine Probleme.

Das Programm "schläft" bei einer FTP-Übertragung ein. Um genauer zu sein, die Oberfläche in einem zu großen Intervall aktuallisiert. Nämlich immer wenn das TOnWork Event von IdFTP eintritt. Und das ist bei großen Dateien und langsamen Verbindungen einfach zu langsam. Außerdem kann man den Verbindungsversuch nicht abbrechen, da Indy den Hauptthread "blockiert". Das sind nur ein paar Schwierigkeiten.

AntiFrezze bringt nichts, da ich die Oberfläche und die Programmligik komplett von einander getrennt habe. Die Infos werden per Procedure of Object ausgetauscht. In anderen Forenbeiträgen wird auch da von berichtet, dass AntiFrezze in manchen Fällen nicht funktioniert.

Nun habe ich mir gedacht, dann mache ich das eben in einem eingenen Thread. Das habe ich in diveren Beiträgen auch schon gelesen. Und ich habe mir auch das Tutorial von Luckie durchgelesen.

Gesagt getan, nicht von TObject abgeleitet sondern von TThread, also meine FTP-Klasse die "Wrapper" für die IdFTP-Klasse dient. Die Methode Execute überschrieben...

Delphi-Quellcode:
procedure TFTPHandle.Execute;
begin
  inherited;

  while not Terminated do
  begin
    WaitFor;
  end;

  OutputDebugString(PChar('Terminated = ' + PChar(BoolToStr(Terminated, True))));
end;
Und nun kommen wir zu meinem Problem. Ich möchte den Thread über Windows-Messages steuern.
Also habe ich mir ein paar Nachichten deklariert:

Delphi-Quellcode:
WM_FTPBase = WM_USER + 1;
WM_FTPConnectToServer = WM_FTPBase + 1;
WM_FTPErrorHappend = WM_FTPBase + 2;
WM_FTPCommandSuccessful = WM_FTPBase + 3;
WM_FTPUploadFileList = WM_FTPBase + 4;
WM_FTPDownloadFileList = WM_FTPBase + 5;
(...)
(Ja, ich weiß man kann den Nachrichten auch Parameter anhängen, dann hätte ich mir ein paar sparen können)

Nun weiß ich nicht wie der Thread auf die Nachrichte reagieren soll.

Ich habe diesen ersten Ansatz:
Delphi-Quellcode:
procedure WMFTPConnectToServer(var Message: TMessage); message WM_FTPConnectToServer;
procedure WMFTPCancelCurrentAction(var Message: TMessage); message WM_FTPCancelCurrentAction;
Diese Methoden werden aber nie aufgerufen, da schon das PostThreadMessage(FTPInstance.ThreadID, WM_EAEFTPConnectToServer, 0, 0) fehl schlägt, d.h. es wird False zurückgegeben. Also GetLastError aufgerufen und was ist darin? Eine "0"...

Noch eine kleine Zusatzinfo, das Objekt FTPIntance wird im initialization-Abschnitt einer anderen Unit erzeugt.

So sieht der constructor aus:
Delphi-Quellcode:
inherited Create(False);
FreeOnTerminate := True;
(...)

Dann gibt es noch ein kleines Problem beim Beenden der Anwendung, wenn ich Terminate aufrufe. Dann ist der Thread auch weg, das kann habe ich mit dem Process Explorer von Sysinternals kontrolliert. Nur leider "hängt" dann der Hauptthread fest.

Noch ein paar kleine Hardware- und Softwareinfos:
Windows XP Pro (SP2)
Delphi 6 Ent mit Update Pack 2
Pentium 4 mit HT

Wäre schön, wenn ihr mir helfen könntet.

MfG

naujo

// Nachtrag:
Den Hänger beim Beenden konnte ich beseitigen.
Im finalization-Abschnitt war noch ein Free vorhanden, dass hab ich jetzt rausgenommen.
Da beim Create ja schon FreeOnTerminate := True festgelegt wurde.
  Mit Zitat antworten Zitat