Einzelnen Beitrag anzeigen

Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#4

Re: Thread ist mit einer Aufgabe fertig: Mainthread mitteile

  Alt 3. Apr 2008, 01:26
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
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat