Dafür eignet sich eine Jobliste doch ganz gut. Pro Datei ein Job. Wenn ein Job fertig ist, teilt er dies dem Hauptthread mit.
Du kannst ja mal schauen, ob Du meine
Workerthreadpool-Klasse verwenden willst. Ich persönlich finde die Unterteilung in einzelne Jobs übersichtlich, zumal Du mit meiner Threadpoolklasse mehrere Dateien gleichzeitig geladen werden können.
Das wäre Alles, was Du implementieren müsstest:
Delphi-Quellcode:
Type
TDownLoadJob =
Class (TWorkerThreadJob)
private
fMyFile :
String;
protected
Procedure Execute(aThread: TWorkerThread);
Override;
Public
Constructor Create (aFileName :
String);
End;
Constructor TDownloadJob.Create (aFileName :
String);
Begin
Inherited Create;
fMyFile := aFileName;
// UsesCOMObjects := True // , falls Du eben COM verwendest
End;
Procedure TDownloadJob.DoShowFinished;
Begin
MainForm.Memo1.Lines.Add(Format('
Download der Datei %s beendet',[fMyFile]));
End;
Procedure TDownloadJob.Execute (aThread : TWorkerThread);
Begin
DoDownloadFile(fMyFile);
aThread.Synchronize (DoShowFinished);
End;
Und dann einfach:
Delphi-Quellcode:
ThreadPool := TWorkerThreadPool.Create(10); // Erzeugt 10 Threads, die die Jobs parallel abarbeiten
ThreadPool.OnJobException := HandleFinishedDownloads; // 'Exceptionhandler' zuweisen
For i:=0 to slFileList.Count-1 do
ThreadPool.AddJob (TDownloadJob.Create (slFileList[i]));
Den Rest erledigt der Threadpool. Die paar Millisekunden, die bei der Rückmeldung verloren gehen, machen rein gar nichts, weil wir ja einen Threadpool haben.
Wenn Du das aber selber basteln willst, und Dein Download-Thread auf gar keinen Fall Synchronize aufrufen soll, dann müsstest Du einen zweiten Thread erzeugen, der eine Stringliste und eine Semaphore verwaltet (Oder Messages, is aber -finde ich- uncool). Dieser 2. Thread wartet also nur darauf, das der Download-Thread ihm etwas in seine Stringliste schreibt und die Semaphore anzuppelt, woraufhin dieser dann kurz aufwacht und schön gemächlich per Synchronize dem Hauptthread die Nachricht(en) in eine Listbox, Memo oder sonstwohin schreibt. Das ginge auch mit Suspend/Resume, aber das mag ich nicht.
Edit: Die erwähnte Workerthreadpool-Klasse unterstützt nun die Benachrichtigung aus einem Job heraus, denn meine o.g. Methode bindet den Job ja an das Formular (über die DoShowFinished-Methode), und das ist nicht gut.