Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi OnWork wird nach Download ausgeführt? (https://www.delphipraxis.net/111050-onwork-wird-nach-download-ausgefuehrt.html)

TheMiller 29. Mär 2008 12:42

Re: OnWork wird nach Download ausgeführt?
 
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

TheMiller 29. Mär 2008 13:33

Re: OnWork wird nach Download ausgeführt?
 
Halt! Neuer Erkenntnis:

Selbst wenn ich ein neues Projekt ohne Container, Thread etc erstelle, tritt der gleiche Fehler auf. Hier nochmal der Code des neuen Projekts

Delphi-Quellcode:
  private
    procedure InternalOnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
  public

procedure TForm1.InternalOnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
begin
  ShowMessage('SD');
  Form1.Caption:=IntToStr(AWorkCount);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  www: TIdHTTP;
  fs: TFileStream;
begin
  fs:=TFileStream.Create(ExtractFilePath(ParamStr(0))+'text.zip', fmCreate);
  www:=TIdHttp.Create(nil);
  [url]www.OnWork:=InternalOnWork;[/url]
  www.Get('http://www.domain.de/updates/Putty.exe', fs);
  ShowMessage('Fertig');
end;
Es erscheint die Message "Fertig" und danach mehrmals "SD" und die Caption verändert sich... Halt alles nach Download! Wieso? :wall: :wall:

Christian Seehase 29. Mär 2008 15:03

Re: OnWork wird nach Download ausgeführt?
 
Moin DJ-SPM,

lass' mal ShowMessage weg.
Das bringt die Verarbeitung der MessageQueue durcheinander.
Benutze, ersatzweise, mal OutputDebugString, dann kannst Du Dir im EventLog-Fenster (Ansicht\Debug Fenster) den Ablauf anschauen.

TheMiller 29. Mär 2008 15:08

Re: OnWork wird nach Download ausgeführt?
 
Ich habe mittlerweile gesehen, dass alles richtig funktioniert, wenn ich eine Datei runterlade, die größer als 2MB ist. Bei kleineren Dateien tritt der Fehler wieder auf. Auch in einem komplett neuen Projekt.

Habe das ShowMessage auch schon weggelassen.

Habe eine MP3-Datei auf einen Server geladen und diese mit dem Programm runtergeladen und es at wunderbar UND synchron funktioniert. Dann wieder eine 1,2MB-Datei und da ging's dann wieder erst NACH dem Download los.

Und von "OutputDebugString" habe ich keine Ahnung. Das sagt mir garnix!

Christian Seehase 29. Mär 2008 15:14

Re: OnWork wird nach Download ausgeführt?
 
Moin DJ-SPM,

OutputDebugString schreibt den angegebenen Text in das Eventlog.
Damit kann man dann wunderbar (vorausgesetzt man schreibt sinnvolle Text weg ;-)) den Ablauf verfolgen.

Das OnWork-Event wird immer ausgelöst, wenn der Buffer gefüllt wurde. Der Default-Wert müsste 32 KB betragen.
In meinem Download-Thread mache ich es mit TidHTTP auch nicht anders, als Du es oben beschrieben hast, und, so wie es aussieht, funktioniert es.

TheMiller 29. Mär 2008 15:18

Re: OnWork wird nach Download ausgeführt?
 
Ja, aber wenn ich doch eine Datei lade, die 1,2MB groß ist, dann werden doch mehrere Male 32kb geschrieben. Also müsste doch auch mehrere male das onWork ausgeführt werden, nämlich immer dann, wenn 32kb voll sind.

Eigentlich wird es ja auch mehrere Male ausgeführt. Nur eben bei Dateien kleiner als xMB nach dem vollständigen Download, bei größeren Dateien (getestet mit MP3-Datei von 4MB) korrekt während dem Download.

Egal was ich mache, alles was in OnWork steht wird je nach Dateigröße mal früher mal später ausgeführt.

das verstehe ich nicht

Christian Seehase 29. Mär 2008 15:35

Re: OnWork wird nach Download ausgeführt?
 
Moin DJ-SPM,

leider kann ich das Problem nicht nachstellen, da ich eine andere Version der Indys verwende (ich weiss nicht einmal welche genau :oops:).
Bei mir ist AWorkCount nicht als const deklariert.

TheMiller 29. Mär 2008 15:38

Re: OnWork wird nach Download ausgeführt?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ich hab mal einen Anhang hochgeladen. Dabei verwende ich auch OutputDebugString... Da habe ich einen RICHTIG-Knop und einen Falsch Knopf. Schau mal bitte.

MrKnogge 29. Mär 2008 16:43

Re: OnWork wird nach Download ausgeführt?
 
Also bei mir funktionieren beide Knöpfe wunderbar, die Progressbar zeigt prima den aktuellen Stand an. Hast du es nur in der IDE getestet, oder auch auserhalb der IDE ?
Was ein Label im OnWork angeht, so bewirkt nach dem Setzen der Caption ein Label.refresh Wunder.

Grüße
Christian

PS: Hast du mal versucht deine Indys zu aktualisieren ?

TheMiller 29. Mär 2008 17:46

Re: OnWork wird nach Download ausgeführt?
 
Also bei mir ist das so (ich habe Windows Vista Business), dass bei Knopf 1 erst eine Weile garnix passiert und dann die Progressbar razz-fazz (oder so) gefüllt wird.

ABER: Ganz generell habe ich solche Sachen schon mit Vista beim Download festgestellt. Zb, wenn ich eine größere Datei per IE runterlade (also komplett ohne Delphi), dann läd der mit 90kb (ich kann mit DSL2000 bei zu 220 laden), sagt, dass es noch 5 Minuten dauert, an auf einmal sagt er, dass er fertig ist.

Da stimmt also generell was mit der Download-Anzeige nicht. 100MB dauern ca 7 Minuten. Manchmal zeigt er also an, dass der Download 20-30 Minuten dauert, läd aber doch (intern) mit der richtigen Geschwindigkeit und sagt dann (nach der richtig Zeit), dass er fertig ist.

Ich weis nicht, wie ich es anders beschreiben soll.

Und die progressbar wird wirklich bei dir nach und nach gefüllt, und nicht erst am Schluss ganz schnell?

[EDIT]Hab's gerade an einem nicht-Vista-Rechner getestet und es funktioniert tatsächlich. Damit bestätigt sich die oben geschriebene Vermutung. Das mit der falschen Download-Anzeige ist wirklich ganz extrem. Ist das ein bekannter Vista-Bug, oder habe mal wieder nur ich so ein Problem?[/EDIT]


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:27 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz