Einzelnen Beitrag anzeigen

alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#9

Re: Thread ist mit einer Aufgabe fertig: Mainthread mitteile

  Alt 3. Apr 2008, 08:10
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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat