Einzelnen Beitrag anzeigen

Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#6

Re: Globale Thread function ?

  Alt 25. Mär 2010, 12:12
Hi,

ich melde mich nochmal in diesem Thread, da das Problem hier im Prinzip noch reinpasst.

Problem ist folgendes. Ich starte von der Mainform aus x Threads nach folgendes Schema:

Delphi-Quellcode:

MainForm:

var
  IndyThread: TDownloadThread;

....

  IndyThread := TDownloadThread.Create(True);
  IndyThread.FreeOnTerminate := True;
  IndyThread.URL := LinkList.Items.Item[i].Caption;
  IndyThread.FilePath := DownloadPfad;
  IndyThread.RsUsername := frmOptions.edtRSUsername.Text;
  IndyThread.RsPassword := frmOptions.edtRSPassword.Text;
  IndyThread.Resume;

  IndyThread := TDownloadThread.Create(True);
  IndyThread.FreeOnTerminate := True;
  IndyThread.URL := LinkList.Items.Item[i].Caption;
  IndyThread.FilePath := DownloadPfad;
  IndyThread.RsUsername := frmOptions.edtRSUsername.Text;
  IndyThread.RsPassword := frmOptions.edtRSPassword.Text;
  IndyThread.Resume;

....
Der Grobe Aufbau des Threads:

Delphi-Quellcode:
unit ThreadUnit;

interface

uses
  Classes, SysUtils, Windows, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdException, ComCtrls;

var
  is_abort: Boolean;

type
  TWorkBeginEvent = procedure(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer) of object;
  TWorkEvent = procedure(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer) of object;
  TWorkEndEvent = procedure(ASender: TObject; AWorkMode: TWorkMode) of object;
  TDownloadThread = class(TThread)
  private
    { Private-Deklarationen }
    FURL: string;
    FID: string;
    FFMessage: string;
    FFilePath: string;
    FFileName: string;
    FWorkCountMax: Integer;
    FWorkCount: Integer;

    IdHTTPDownload: TIdHTTP;
    filestream: TFileStream;

    procedure ShowStatus;
    procedure ShowEnd;
    procedure Error;
    procedure Successful;
    procedure Abort;
    procedure FWorkBeginEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
    procedure FWorkEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
    procedure FWorkEndevent(ASender: TObject; AWorkMode: TWorkMode);
  public
    property URL: string read FURL write FURL;
    property FilePath: string read FFilePath write FFilePath;
  protected
    procedure Execute; override;
  end;

implementation

uses
  MainU, GlobalsU;


{ TDownloadThread }


procedure TDownloadThread.Execute;
begin
  IdHTTPDownload := TIdHTTP.Create(nil);
  is_abort := False;

  try

    IdHTTPDownload.OnWorkBegin := FWorkBeginEvent;
    IdHTTPDownload.OnWork := FWorkEvent;
    IdHTTPDownload.OnWorkEnd := FWorkEndevent;


    FFileName := SetFileName(FURL);
    FID := FFileName;

    filestream := TFileStream.Create(FFilePath + FFileName, fmCreate);

    try
      IdHTTPDownload.Get(FURL, filestream);
    except
      on E: Exception do
      begin
        FFMessage := E.message;
        Synchronize(Error);
      end;
    end;

  finally
    IdHTTPDownload.Free;
    filestream.Free;
  end;
end;


procedure TDownloadThread.FWorkBeginEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
begin
  FWorkCountMax := AWorkCountMax;

  Synchronize(ShowStatus);
end;


procedure TDownloadThread.FWorkEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
begin
  FWorkCount := AWorkCount;
 
  if is_abort then
    Synchronize(Abort); // Wenn is_abort dann Download abbrechen

  // Berechnen der Statuswerte


  Synchronize(ShowStatus);
end;


procedure TDownloadThread.FWorkEndevent(ASender: TObject; AWorkMode: TWorkMode);
begin
  if not is_abort then
  begin
    Synchronize(ShowEnd);
    Synchronize(Successful);
  end;
end;


procedure TDownloadThread.ShowStatus;
begin
  // Zugriff auf die Vcl der Mainform
end;


procedure TDownloadThread.Successful;
begin
  // Zugriff auf die Vcl der Mainform
end;

procedure TDownloadThread.ShowEnd;
begin
  // Zugriff auf die Vcl der Mainform
end;

procedure TDownloadThread.Error;
begin
  // Zugriff auf die Vcl der Mainform
end;

procedure TDownloadThread.Abort;
begin
  // Download abbrechen
  IdHTTPDownload.Disconnect;
  // Zugriff auf die Vcl der Mainform
end;


end.
Nun möchte ich die thrads abbrechen. Das mache ich momentan indem ich eine Globale variable is_abort in der Thread Unit definiert habe und alle Threads im OnWork prüfen ob is_abort true oder false ist.

Im Prinzip funktioniert das auch. Ist allerdings nicht sonderlich schön wie ich finde (TDownloadThread.Abort wird auch mehrmals aufgerfufen, bevor das Disconnect wirklich gegriffen hat.

Gibt es eine Möglichkeit das ganze nicht über eine Variable zu prüfen, sondern eine Procedure oder ein Event das ich von der Mainform aus aufrufen kann, welches dann in allen Threads aufgerufen wird ?

Mfg Yannic
  Mit Zitat antworten Zitat