Zitat von
Dax:
Du kannst Synchronize benutzen, das sollte kein Problem darstellen. Dazu schreibst du dir eine Methode in die Threadklasse, die - in einer Critical Section - beim Hauptthread anklopft, sich selbst in die Liste wartender Threads einfügt und sich dann schlafen legt, nachdem du die CS geschlossen und über Synchronize dem Hauptthread Bescheid gesagt hast, dass da was wartet. Der Hauptthread schnappt sich nun die Liste und verteilt neue Aufgaben an die Threads, weckt sie wieder auf und das Spiel geht von vorne los.
Sorry Dax, aber das klingt etwas "konfus"
Also ich habe einen Mainthread (MT) und einen Downloadthread (DT).
Der DT macht also folgendes:
- CS.Enter
- Sync(MTMethode)
- "Liste wartender Threads?"
- CS.Leave
- Suspend
Aber was ich möchte ist ja folgendes:
Code:
DT
|
|
|
Download fertig MT
|------------------> Aha :)
DL fertig
Weitere Datei | (Ein paar Sachen machen)
downloaden (wenn da) |
v v
Wobei alles was dort beim MT abläuft im Kontext von "Sync" aufgerufen würde.
Zitat von
Luckie:
Wie erzeugst du den Thread? Mit der TThread-Klasse der
VCL oder mit
BeginThread?
Es ist die
VCL TThread-Klasse.
Zitat von
Luckie:
Wenn ersteres, die Thread-Klasse kennt das Ereignis OnTerminate, welches aufgerufen wird, wenn die Execute Methode verlassen wird.
Theoretisch wird sie nie verlassen
Nur wenn das Programm beendet wird.
Aktuell sieht der Code folgendermassen aus:
Delphi-Quellcode:
procedure TDownloadThread.Execute;
var
i, j: Integer;
fs : TFileStream;
fn : string;
breaked : Boolean;
FDownload : TIdHTTP;
FSource, FDestination : string;
FExtract : Boolean;
begin
// Initiate Downloader
FDownload := TIdHTTP.Create(nil);
try
// Searching until stopped
while true do
begin
try
// Searching all entrys
i := 0;
while i < FList.Count do
begin
// Searching threadsafe
FList.EnterCritical;
try
// Searching for a ready entry or end of the list
while (i < FList.Count) and (FList[i].Status <> dsReady) do
Inc(i);
if i < FList.Count then
begin
// Found a file to download
[...] // Only downloadcode
// Send message to Mainthread: Download complete
end;
finally
FList.LeaveCritical;
end;
end;
finally
Suspend;
end;
end;
finally
FreeAndNil(FDownload);
end;
end;
Wie man sieht, habe ich mehrere Schleifen.
Die äußerste sorgt dafür, dass durch "Resume" der Thread immer wieder angeworfen werden kann.
Die nächst innere sorgt dafür dass er solange sucht, bis er alle Einträge durch ist.
Die innerste sorgt dann dafür dass diejenigen übersprungen werden, die gedownloadet werden, gedownloadet sind, oder noch nicht fertig sind.
Ich habe mich dabei für drei Schleifen entschieden, da ich somit einfach mit den CriticalSections verhindern kann, dass während der Suche nicht an der Liste gearbeitet wird.
MfG
xZise