Hallo,
ich arbeite an einem kleinen Mail-Programm welches auf den
Indy-Komponenten basiert. Den "
Indy-Layer" habe ich in Komponenten verpackt, welche die Verbindung aufbaut und halten soll, Downloads und Löschen von Mails etc. behandeln soll.
Da mein Programm dies im Hintergrund erledigen können soll - momentan freezed es ziemlich häufig, bi unterschiedlichen Aktionen - habe ich versucht diese Klasse(n) in Threads zu packen, welche einmal gestartet solange idlen sollen, bis ein Kommando, wie Download, Lösche oder Disconnect vom Hauptthread des Programms kommt. Dazu leite ich meine Basisklasse von TThread ab (ein Auszug aus meinem Programm):
Delphi-Quellcode:
TConnection = class(TThread) //ist quasi ne abstrakte klasse
protected
IdSSLIO: TIdSSLIOHandlerSocketOpenSSL;
procedure Execute; override;
published
IdMessage: TIdMessage;
constructor Create(); virtual;
destructor Destroy; override;
function Connect: Boolean; virtual; abstract;
procedure Disconnect; virtual;
function IsConnected: Boolean;
function IsReaded(idx: Integer): Boolean;
function IsWorking: Boolean;
procedure LoadMsg(index: Integer; full: boolean); virtual; abstract;
procedure Refresh(LV: PListView); virtual; abstract;
procedure Save; virtual; abstract;
procedure SetAllItemsToReaded(ListView: TListView = nil);
procedure SetAllItemsToUnreaded(ListView: TListView = nil);
procedure SetReaded(idx: Integer; ListView: TListView);
procedure SetUnreaded(idx: Integer; ListView: TListView);
end;
TConPOP3 = class(TConnection) //Lokale MailBox Verwaltung
private
IdPOP3: TIdPOP3;
procedure CreatePOP3;
public
constructor Create(); override;
destructor Destroy; override;
function Connect: Boolean; override;
procedure DelMail(index: Integer);
procedure Disconnect; override;
function GetUIs: TStrings;
procedure LoadMsg(index: Integer; full: boolean); override;
procedure Refresh(Sender: TObject);
procedure RecreatePOP3;
procedure ReRetrieve(index: Integer);
procedure ResetPOP3;
function RetrieveRAW(index: Integer): TStrings;
procedure Save; override;
end;
Das ganze war bisher eine ganz normale Klasse. Daher hier die Änderungen die ich vorgenommen habe, damit die Klasse in einem Thread läuft:
Delphi-Quellcode:
constructor TConnection.Create();
begin
inherited Create(True);
//hier steht noch irrelevanter alter Code
FreeOnTerminate := True;
Priority := tpIdle;
Resume;
end;
procedure TConnection.Execute;
begin
WaitFor;
//Never reachs this line!!!
end;
Soweit ich im Debugger sehe, werden die Threads erzeugt und existieren bis zum Programmende bzw. da wo ich sie mit ConPOP3.Free; beende. Fehlermeldungen, Speicherzugriffsverletzung oder Exceptions bekomme ich auch keine (mehr).
Mein eigentliches Problem ist, dass ich mir halt denke bei nem Aufruf:
Delphi-Quellcode:
{1} StatusPanel.Visible := true; //<1 sek.
{2} ConPOP3.LoadMsg(SelectedIndex, true); //20-30 sek.
{3} StatusPanel.Visible := false; //<1 sek.
sollte, erst 1, dann 2 "und" 3 so ausgeführt werden, dass die Befehle in der Reihenfolge: 1,3,2 fertig werden. Jedoch wird 2 ausgeführt als wenn es in keinem Thread drin stecken würde, so dass ich auf die Reihenfolge 1,2,3 komme :-/
Langsam bin ich ratlos, weil ich bisher bzgl. der Freezes immer nur die Tipps finde "Packs doch einfach in einen Thread" ohne weitere Ausführung. Und bei den Thread-Problemen geht es immer nur um Synchronisationsprobleme, sowie bei den Thread-Tutorials pro Thread immer nur eine fest verdrahtete Funktion zu haben :-/