Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Paralleler Download


ruewue - Do 04.11.10 09:42
Titel: Paralleler Download
Hallo zusammen,

ich habe ein kleines Problem. Ich muss nachts via Programm 7 Dateien von einem Server runterladen. Diese Dateien werden aber zu unterschiedlichen Zeiten, und das auch noch unregelmäßig, auf den Server gestellt. Anschließend findet eine getrennte Weiterverarbeitung statt. Da ich aus zeitlichen Gründen nicht warten kann, bis alle Dateien da sind, da ich zu einen Zeitpunkt X alle ergebnisse wieder zurückladen muss, versuche ich die jeweilige Datei in einem eigenen Thread zu suchen und runter zu laden. Dies funktioniert auch, wenn die Threads nach einander laufen. Wenn ich jedoch zwei threads gleichzeitig am Laufen habe funktioniert es nicht mehr. Es wird mir jedes mal beim Start des 2. Threads eine ThreadError Meldung ausgegeben und es wird nichts mehr geladen.

Kann man eigentlich in 7 Threads parallel Downloads ausführen? Oder gibt es da noch eine andere Methode?

Danke für eure fachliche Hilfe.


bummi - Do 04.11.10 09:46

prinzipell ja, wenn die Komponenten Threadsave sind.
Ansonsten, da viele Komponenten Async arbeiten (intern Threaden), einfach mehrere Komponenten im Mainthread arbeiten lassen.


matze - Do 04.11.10 10:10

Es würde helfen, wenn du einfach mal deinen Code zeigen würdest. Mit diesen wenigen Informationen kann ja niemand was anfangen!


jaenicke - Do 04.11.10 10:31

user profile iconruewue hat folgendes geschrieben Zum zitierten Posting springen:
Es wird mir jedes mal beim Start des 2. Threads eine ThreadError Meldung ausgegeben und es wird nichts mehr geladen.
Dann greifst du vermutlich auf etwas aus dem Hauptthread bzw. deinem Hauptformular zu.

Böser Verdacht, ich hoffe ich irre mich:
Kann es sein, dass du eine Komponente für die Downloads auf dem Formular hast und von den Threads aus darauf zugreifst?


ruewue - Do 04.11.10 15:09

@matze:

hier einen groben Ausschnitt aus den Source. Der original Source ist sehr umfangreich. Habe alle relevanten Punkte aufgezeichnet. Die rausgefilterten Stellen funktionieren aber alle. Die FTP Verbindung wird im TfrmMain.FormCreate() aufgebaut.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
....
type
  TInfo  = Record
    Name  : String;
    Ein  : String;  
    Aus  : String;  
    Size  : Integer;
    Found  : Boolean;
    Load  : Boolean;
    OK  : Boolean;
    Error  : Boolean;
  end;

  ThreadSTO = class(TThread)
    private
      { Private-Deklarationen }
    protected
      procedure Execute; override;
  end;

  ThreadPRO = class(TThread)
    private
      { Private-Deklarationen }
    protected
      procedure Execute; override;
  end;

var
  LoadSTO        : ThreadSTO;
  LoadPRO        : ThreadPRO;
  fStock      : TInfo;
  fPROrders    : TInfo;
  
...  
   
procedure TfrmMain.TimMasterTimer(Sender: TObject);
begin
  if FormatDateTime('hh:mm', now) = fStock.Ein then begin
  LoadSTO.FreeOnTerminate  := true;
  LoadSTO.Resume;
  end;

  if FormatDateTime('hh:mm', now) = fPROrders.Ein then begin
  LoadPRO.FreeOnTerminate  := true;
  LoadPRO.Resume;
  end;
  
  ...

end;

...

procedure ThreadSTO.Execute
begin
...
  ftp.Get(fStock.Name, fStock.Name, true);
...  
  LoadSTO.Suspend;
end;

procedure ThreadPRO.Execute
begin
...
  ftp.Get(fPROrders.Name, fPROrders.Name, true);
...  
  LoadPRO.Suspend;
end;



Danke schon mal für die Hilfe

Moderiert von user profile iconMartok: Delphi-Tags gesetzt


jaenicke - Do 04.11.10 15:15

user profile iconruewue hat folgendes geschrieben Zum zitierten Posting springen:
Die FTP Verbindung wird im TfrmMain.FormCreate() aufgebaut.
Also war mein Verdacht doch richtig. Du erzeugst das FTP-Objekt im Hauptthread und versuchst dann parallel auf genau die selben Variablen, Felder und Daten zuzugreifen. Das kann nicht klappen...

Du darfst im Thread auch nur auf Sachen zugreifen, die dem Thread gehören. Zugriffe nach außen musst du synchronisieren, damit sie im Kontext des Hauptthreads laufen.


ruewue - Do 04.11.10 16:16

@jaenicke:

Danke für den Hinweis. Wenn ich den FTP Zugriff im Hauptthread laufen lassen, so kann ich ja nur einen zur Zeit laufen lassen. Ich brauche aber mehrere parallel. Soll ich nun für jeden Thread einen eigenen FTP-Zugriff erzeugen?

Im Moment habe ich mir damit geholfen, dass ich die Threads parallel laufen lasse, aber die Downloads nur jeweils einer zur Zeit läuft.

Danke aber für die Hilfe !


jaenicke - Do 04.11.10 17:08

Ja, da brauchst du mehrere FTP-Objekte, für jeden Thread eins.


Dude566 - Do 04.11.10 19:16

Stell dir doch mal vor, alle Threads greifen auf die Methoden deiner FTP Komponente zu und wollen diese gleichzeitig nutzen, das kann ja nicht funktionieren, da muss schon für jeden Thread eine eigene Instanz der Komponente her. ;)


jaenicke - Do 04.11.10 20:32

Einfaches Beispiel:
Stell dir vor du möchtest deinen Garten bewässern. Damit es schneller geht, möchtest du das Wasser gleichzeitig zu mehreren Rasensprengern "herunterladen" :mrgreen:.

Naja, und jetzt versuch mal das mit einem Schlauch für alle drei Rasensprenger gleichzeitig zu machen. ;-)


ruewue - Mi 17.11.10 10:37

Danke noch mals an alle. Habe das Problem mit 3 Threads und jeweils eigenem Serverzugriff gelöst. Läuft super.

Gruß
Rüdiger