Einzelnen Beitrag anzeigen

Benutzerbild von meolus
meolus

Registriert seit: 28. Aug 2005
Ort: Aachen
20 Beiträge
 
Delphi 2006 Professional
 
#1

Wie Klasse in Thread packen?

  Alt 6. Apr 2008, 13:35
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 :-/
Real programmers don't comment their code;
if it was hard to write, it should be hard to read.
  Mit Zitat antworten Zitat