AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Pagecontrol und Threads?

Ein Thema von Chriscode · begonnen am 16. Feb 2012 · letzter Beitrag vom 17. Feb 2012
Antwort Antwort
Chriscode

Registriert seit: 18. Aug 2009
32 Beiträge
 
#1

Pagecontrol und Threads?

  Alt 16. Feb 2012, 09:58
Hallo zusammen,
ich programmiere gerade eine Updatefunktion die eine Art Downloadmanager beinhaltet. Für die Downloads benutze ich die Klasse TThread. Meine Updatefunktion übergibt die Downloadlinks zu mehrere zu erneuernde Dateien und erzeugt für jede Datei ein TabSheetEx, den Downloadthread und eine progressbar auf der PageControl. Da die Dateien teilweise recht groß sind sollten diese parallel heruntergeladen werden können.

Im Prinzip geht es mir nur darum, den Fortschritt der einzelnen Dateien optisch mit Progressbars darzustellen.

Jetzt habe ich mir das IndyHTTPGetThreaded Demo von Luckie heruntergeladen (an dieser Stelle vielen Dank dafür) und stehe nun vor dem Problem die Threads mit der Pagecontrol / dem Tabsheet zu "verbinden". Oder besser gesagt: Wie kann ich dem Thread mitteilen welche Page zu ihm gehört?

Meine Progressbar kann ich ja z.B. so mit dem Tabsheet verbinden:
Code:
probar := TProgressbar.Create(TabSheetEx);
TOleControl(TabSheetEx.probar).Parent := TabSheetEx;
Die Downloadthreads müssen ja wissen auf welchem Tabsheet sie aktiv sind und auf diesem dann die Progressbar verändern, den Tab schließen etc. Das Problem ist nicht grundlegende Funktionsweise von beiden Punkten sondern wie ich sie kombinieren kann.

Ich hoffe meine Fragestellung ist konkret genug um sie beantworten zu können. Mein Problem ist, mir fehlt eben schon ein vernünftiger Ansatz. Oder ist die Idee über das Tabsheet hier generell zu umständlich?

Vielen Dank.

Gruß
Chris
Chris

Geändert von Chriscode (16. Feb 2012 um 10:09 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 10:12
Spendier Deiner Threadklasse doch einfach ein Event, das sie alle X heruntergeladenen Bytes feuern kann.
Delphi-Quellcode:
type
  TDownloadEvent = procedure(Sender: TObject; CurrentSize, TotalSize: int64) of object;

  TDeinThread = class(TThread)
  private
    FDownloadEvent: TDownloadEvent;
    procedure DoOnProgress;
    ...
  public
    ...
    property DownloadEvent: TDownloadEvent read FDownloadEvent write FDownloadEvent;

procedure TDeinThread.Execute;
begin
  //arbeiten
  if (HeruntergeladeneBytes mod 500 = 0) then
    Synchronize(DoOnProgress);
  ...
end;

procedure TDeinThread.DoOnProgress;
begin
  if Assigned(FDownloadEvent) then
    FDownloadEvent(self, HeruntergeladeneBytes, BytesGesamt);
end;
Den Thread muss Du nun noch Suspended anlegen, damit Du noch die Properties zuweisen kannst, und dann sollte das im Groben funktionieren.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Chriscode

Registriert seit: 18. Aug 2009
32 Beiträge
 
#3

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 10:23
Hallo Detlef,
vielen Dank für deine Antwort.

Ich glaube du bist mir allerdings gedanklich schon mehr als ein paar Schritte voraus

Bei deinem Beispiel wüsste ich nicht wo jetzt konkret auf die Progressbar des Tabsheets zugegriffen wird. Und woher der Downloadthread weiß auf welchem Tab er beheimatet ist?

Mir fehlt anscheinend einfach das Wissen wie sich beides kombinieren lässt.

Meinen Downloadthread starte ich so:
Code:
 DownloadThread := TDownloadThread.Create(True);
   DownloadThread.FreeOnTerminate := True;
   DownloadThread.URL := updatesrc;
   DownloadThread.start;
Demnach weiß der Downloadthread überhaupt nicht zu welchem Tab er gehört

Gruß
Chris
Chris
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 10:32
Der Thread selbst gehört ja zu gar keinem Tab. In meinem Beispiel würdest Du nun 3 Methoden anlegen (geht auch mit einer, aber wir machen es erst einmal einfach) und diese dem Event des jeweiligen Threads zuweisen.
Delphi-Quellcode:
DownloadThread := TDownloadThread.Create(true);
DownloadThread.DownloadEvent := ProgressMethod;
Wobei ProgressMethod dann eine Methode vom Typ TDownloadEvent ist, also die Parameter Sender, CurrentSize und TotalSize besitzt.
Delphi-Quellcode:
procedure TTabForm.ProgressMethod(Sender: TObject; CurrentSize, TotalSize: int64);
begin
  (* Aus Jux selbst berechnet *)
  ProgressBarThread1.Position := Round(CurrentSize / TotalSize * 100);
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Chriscode

Registriert seit: 18. Aug 2009
32 Beiträge
 
#5

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 11:10
Hallo nochmal,
erneut meinen herzlichen Dank an dich für deinen hilfreichen Beitrag.

Was ich jetzt wieder einmal nicht weiß, wie kann ich die richtige Progreessbar ansprechen? Du schreibst "ProgressBarThread1". Die Progressbar lasse ich ja dynamisch erzeugen. Das ist ja genau der Punkt den ich Anfangs meinte. Ich hatte überlegt namen zu übergeben und findcomponent zu nutzen, aber das kann wohl nicht im Sinne des Erfinders sein.

Im übrigen erhalte ich die Fehlermeldung "ungültige GLeitkommaoperation" an der Stelle deiner Jux-Berechnung Aber das könnte natürlich auch daran liegen das ich die falsche progressbar anspreche. Ich habe nämlich einfach "probar.position" genommen.

Gruß
Chris
Chris

Geändert von Chriscode (16. Feb 2012 um 11:15 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 12:06
Du brauchst keinen Namen für die Progressbar, sondern kannst ja auch die Instanz selbst ansprechen. Die musst Du Dir halt irgendwo merken, am Besten verknüpfst Du sie dann gleich mit der Thread-Instanz (wie, das überlasse ich Dir). Der Fehler dürfte übrigens daher rühren, dass TotalSize nahe gegen 0 geht oder gar 0 ist, das gibt dann natürlich Probleme bei der Division. Aber darum ging es ja auch gar nicht
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Chriscode

Registriert seit: 18. Aug 2009
32 Beiträge
 
#7

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 13:14
okay... ich komme mir langsam wirklich hilflos vor. Du hast mir jetzt schon ordentlich weitergeholfen aber der Funke will nicht gänzlich überspringen.

Könntest du mir nicht vielleicht ein kleines -meinetwegen auch allgemeines- Beispiel geben wie ich dies anstellen kann?

Mir gehts jetzt weniger konkret um die Progressbar das muss ich selbst hinbekommen. Vielmehr darum wie der Thread eben die Komponenten von der Page ansteuern kann. Das was nunmal auch meine Ausgangsfrage war.

Mit der Prozedur habe ich jetzt schonmal ein gutes Werkzeug zur Hand aber ich weiß nicht wie es genau anwenden kann.

Also nochmal ganz konkret gefragt:
1) Wie kann ich den Sheet an sich ansprechen der zur Prozedur gehört und diesen z.B. schließen?
(Komponente.pages[?] as TTabSheetEx).free ?

2) Wie kann ich Komponenten auf dem Sheet ansteuern z.B die Progressbar?

Gruß
Chris
Chris

Geändert von Chriscode (16. Feb 2012 um 13:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Pagecontrol und Threads?

  Alt 16. Feb 2012, 13:32
Da gibt es mehrere Möglichkeiten. Die Einfachste wäre, dem Thread eine Property vom Typ TProgressBar zu verpassen. Dann könnte man sich auch das Event sparen, da dann der Thread direkt auf seine Property zurückgreifen und sie synchronisiert aktualisieren könnte. Der Nachteil ist die starke Bindung, denn wenn man später einmal die ProgressBar gegen z.B. eine TGauge austauschen möchte, muss man an mehreren Stellen ändern. Um also flexibel zu bleiben, lassen wir unseren Event so wie er ist. Nun müssen wir noch irgendwie Thread und das zu aktualisierende Control miteinander verknüpfen. Das ginge beispielsweise mit einem Record und einer Liste.
Delphi-Quellcode:
type
  PVerknuepfung = ^TVerknuepfung;
  TVerknuepfung = record
    Thread: TDownloadThread;
    ProgressBar: TProgressBar;
  end;
Wenn wir nun noch eine TList anlegen, können wir dort Elemente vom Typ PVerknuepfung reinpacken.
Delphi-Quellcode:
var
  Verknuepfung: PVerknuepfung;
  PB: TProgressBar;
  DT: TDownloadThread;
begin
  PB := TProgressBar.Create(nil);
  PB.Parent := ...
  //usw.
  DT := TDownloadThread.Create;
  //usw.
  New(Verknuepfung);
  Verknuepfung^.Thread := DT;
  Verknuepfung^.ProgressBar := PB;
  Liste.Add(Verknuepfung);
end;
Wenn nun einer der Threads das Event feuert, könnte man die Liste durchlaufen und schauen, in welchem Element er drinsteht (er übergibt sich ja selbst im Sender-Parameter).
Delphi-Quellcode:
Index := 0;
PB := nil;
while (Index < Liste.Count) and not Assigned(PB) do
  begin
    if TVerknuepfung(Liste[Index]^).Thread = Sender then
      PB := TVerknuepfung(Liste[Index]^).ProgressBar;
    inc(Index);
  end;
So, nun haben wir die zugehörige ProgressBar ermittelt (oder auch nicht, dann ist sie nil) und können sie aktualisieren.
Delphi-Quellcode:
if Assigned(PB) then
  PB.Position := ErrechneterWert;
Das mag jetzt nicht die allereleganteste Methode sein, sie sollte aber eigentlich funktionieren (ohne Gewähr, da aus dem Kopf getippt) und halbwegs verständlich sein.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Chriscode

Registriert seit: 18. Aug 2009
32 Beiträge
 
#9

AW: Pagecontrol und Threads?

  Alt 17. Feb 2012, 10:48
Hallo Detlef,
vielen Dank, du hast mir mit deinen Beiträgen sehr geholfen

Gruß
Chris
Chris
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Pagecontrol und Threads?

  Alt 17. Feb 2012, 10:54
Das freut mich
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:48 Uhr.
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