Einzelnen Beitrag anzeigen

Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#21

Re: OnWork wird nach Download ausgeführt?

  Alt 29. Mär 2008, 12:42
Hallo, es funktioniert leider immernoch nicht. Kann das vielleicht daran liegen, dass der Thread innerhalb einer Containerklasse aufgerufen wird? Hier mal der relevante Quelltext:

Erstmal die Hauptform

Delphi-Quellcode:
  private
    procedure ShowWork(Sender: TObject; AWorkCount: Integer);
  end;

procedure TForm1.ShowWork(Sender: TObject; AWorkCount: Integer);
begin
  Form1.Caption:=IntToStr(AWorkCount);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Updater ist global!
  Updater:=TContainer.Create;
  Updater.SeekUpdates;
  Updater.onAfterCheck:=Updates;
  Updater.onFileComplete:=Complete;
  Updater.OnWork:=ShowWork;
end;
Hier die Containerklasse mit dem Thread

Delphi-Quellcode:

// Der Container
type
  TAfterUpdateCheck = procedure(Sender: TObject) of Object;
  TFileComplete = procedure(Sender: TObject) of Object;
  TOnWorkEvent = procedure(Sender: TObject; AWorkCount: Integer) of object;

  TContainer=class(TSimpleRWSync)
    //[...]
  private
    FOnWorkEvent: TOnWorkEvent;
    procedure InternalOnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
    procedure DoNotifyWork;
  public
    property OnWork: TOnWorkEvent read FOnWorkEvent write FOnWorkEvent;

// Der Thread
type
  TDownloadThread = class(TThread)
  public
    FParent: TContainer;
    SeekUpdates: Boolean;
    Download: Boolean;
    DownloadDest: String;
    DownloadPath: String;
    DownloadFile: String;
  private
    procedure WorkProgress(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
  protected
    procedure Execute; override;
  end;

procedure TDownloadThread.Execute;
var
  www: TIdHTTP;
  fs: TFileStream;
  ini: TMemInifile;
  i, size, imp: Integer;
  Title, Filename, Version, Desc, Path: String;
  PlugIn: Boolean;
  tmpUpdates, Updates: TStrings;
begin
  www:=TIdHTTP.Create(nil);
  try
   //[...]
    if (Download) then
    begin
      www:=TIdHttp.Create(nil);
      [url]www.OnWork:=FParent.InternalOnWork;[/url]
      fs:=TFileStream.Create(DownloadDest+DownloadFile, fmCreate);
      try
        www.Get(DownloadPath+'/'+DownloadFile, fs);
      finally
        [url]www.Free;[/url]
      end;
      if Assigned(FParent.fOnFileComplete) then Synchronize(FParent.DoFileComplete);
    end;
  finally
    fs.Free;
    ini.Free;
    Updates.Free;
  end;
end;

//===== Container =======

procedure TContainer.InternalOnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
begin
  FWorkCount := AWorkCount;
  TDownloadThread.Synchronize(nil, DoNotifyWork);
end;

procedure TContainer.DoNotifyWork;
begin
  Assert(Assigned(FOnFileComplete));
  OnWork(Self, FWorkCount);
end;

procedure TContainer.SeekUpdates;
var
  Dt: TDownloadThread;
begin
  Dt:=TDownloadThread.Create(True);
  Dt.FreeOnTerminate:=True;
  Dt.FParent:=Self;
  Dt.SeekUpdates:=True;
  Dt.Download:=False;
  Dt.Resume;
end;
Es sollte so sein, dass das MainForm dem Container sagen soll, dass er den Download starten muss, der Container sammelt in einem Array die Downloads und startet intern den Download-Thread. Die Dateien werden runtergeladen und das OnWork von TIdHTTP sollte durch den Container in die MainForm gereicht werden. Das klappt, aber erst, wenn die Datei schon geladen wurde. Danach wird das OnWork mehrmals (ca 5-7 mal) ausgefüht.

Wenn ich TFileStreamEx verwende, passiert leider garnichts. Ich habe auch die Klasse korrigiert (MemoryStream -> FileStream) Vielleicht liegst an meiner Container-Thread-Konstruktion

Danke
  Mit Zitat antworten Zitat