![]() |
Threads nacheinander ausführen
Hallo,
arbeite mal wieder ein bissl mit Threads. Möchte Downloads von Dateien durchführen. Diese Daten sollen nacheinander geladen werden und nicht parallel. Momentan werden die Threads gleichzeitig gestartet und demnach laufen sie auch parallel. Hier mal mein Code: (Dies ist ein Auszug aus meiner "Updater-Unit")
Delphi-Quellcode:
(hier die Hauptanwendung)
TDownloadUpdate = class(TThread)
private fFile: String; fUrl: String; fParent: HWND; procedure SetFile(Value: String); procedure SetUrl(Value: String); public Done: Boolean; constructor Create; protected procedure Execute; override; published property File2Load:String read fFile write SetFile; property Url: String read fUrl write SetUrl; end; procedure TDownloadUpdate.Execute; var www: TIdHttp; fs: TFileStream; begin inherited; www:=TIdHttp.Create(nil); [url]www.Port:=81;[/url] // Nur testweise, da Apache auf 81 lauscht. try try ForceDirectories(ExtractFilePath(ParamStr(0))+'\Updates\'); fs:=TFileStream.Create(ExtractFilePath(ParamStr(0))+'Updates\'+fFile, fmCreate); www.Get(fUrl, fs); except // end; finally [url]www.free;[/url] fs.Free; end; end; procedure TUpdater.DownloadUpdate(i: Integer); var du: TDownloadUpdate; begin du:=TDownloadUpdate.Create(); with (du) do begin FreeOnTerminate:=True; SetFile(GetUpdateInfo(i, 'filename')); SetUrl(GetUpdateInfo(i, 'url')); Resume; end; end;
Delphi-Quellcode:
Vielen Dank im Voraus!
procedure TForm1.StartUp;
begin Updater:=TUpdater.Create; Updater.SeekUpdates('http://127.0.0.1/test/updates.ini', Self.Handle); end; procedure TForm1.PngBitBtn2Click(Sender: TObject); begin Updater.DownloadUpdate(0); Updater.DownloadUpdate(1); end; |
Re: Threads nacheinander ausführen
Wenn es nacheinander sein soll, brauchst eigentlich keine Threads oder nur einen
|
Re: Threads nacheinander ausführen
Das verstehe ich nicht ganz. Ich lager das in Threads nur aus, damit das Programm nicht einfriert und ich kein Application.ProcessMessages verwenden muss.
Mehrere Threads habe ich, damit ich auch einzelne Dateien (und nicht alle) runterladen muss. Weiterhin möchte ich pro Datei Downloadstatus und weitere Infos anzeigen. |
Re: Threads nacheinander ausführen
Würde es nicht reichen, einem Thread alle Dateien, die runtergeladen werden sollen, zu übergeben und der diese nacheinander runterlädt?
|
Re: Threads nacheinander ausführen
Delphi-Quellcode:
function MyWaitFor(Event: THandle): Boolean; // von negaH: [url]http://www.delphipraxis.net/post696510.html#696510[/url]
begin Result := False; while not Result do case MsgWaitForMultipleObjects(1, Event, False, INFINITE, QS_ALLINPUT) of WAIT_OBJECT_0: Result := True; WAIT_OBJECT_0 + 1: begin Application.ProcessMessages; if Application.Terminated then Exit; end; else RaiseLastWin32Error; end; end; constructor TDownloadUpdate.Create(aFilename, aURL: string; aFinishEvent: Cardinal); begin inherited Create(True); fFile := aFilename; fUrl := aURL; fFinishEvent := aFinishEvent; FreeOnTerminate := True; resume; end; procedure TDownloadUpdate.Execute; var www: TIdHttp; fs: TFileStream; begin inherited; www:=TIdHttp.Create(nil); [url]www.Port:=81;[/url] // Nur testweise, da Apache auf 81 lauscht. try try ForceDirectories(ExtractFilePath(ParamStr(0))+'\Updates\'); fs:=TFileStream.Create(ExtractFilePath(ParamStr(0))+'Updates\'+fFile, fmCreate); www.Get(fUrl, fs); except // end; finally [url]www.free;[/url] fs.Free; SetEvent(fFinishEvent); end; end; procedure TUpdater.DownloadUpdate(i: Integer); var Event: THandle; begin Event := CreateEvent(nil, False, False, 'ThreadFinished'); TDownloadUpdate.Create(GetUpdateInfo(i, 'filename'), GetUpdateInfo(i, 'url'), Event); MyWaitFor(Event); CloseHandle(Event); end; |
Re: Threads nacheinander ausführen
Hm.. das wäre sicherlich eine gute Alternative. Würde sich in meinem Projekt auch realisieren lassen. Aber ich würde trotzdem gerne wissen, wie ich Threads nacheinander laufen lassen kann. Einfach auch Interesse.
Roter Kasten: Ok, super ;) Werde ich dann auch mal ausprobieren. Danke! |
Re: Threads nacheinander ausführen
Man könnte mit
![]() |
Re: Threads nacheinander ausführen
Ich würde das straight-forward machen, genauso wie Du es willst:
Threads nacheinander ausführen = Thread Nr.X startet Thread Nr.(X+1) Du erstellst Dir eine Liste aller Threads und sorgst dafür, das ein Thread beim Beenden (OnTerminate) den nächsten Thread aktiviert.
Delphi-Quellcode:
So kannst Du dir das 'warten auf den nächsten Thread' sparen. Die Variable 'CurrentThread' benötigst Du, wenn Du die Anwendung beenden willst, und noch nicht alle Threads abgearbeitet sind. Dann Terminierst Du den 'CurrentThread' und löschst einfach die MyThreadList.
Var
MyThreadList : TList; // Of Threads CurrentThread : TMyThread; Procedure TMainForm.RunNextThread (Sender : TObject); Begin If MyThreadList.Count>0 Then Begin // Wenn noch Threads abzuarbeiten sind, CurrentThread := TMyThread(MyThreadList[0]); // nimm den nächsten, MyThreadList.Delete(0); // entferne ihn aus der Liste CurrentThread.Resume; // und führe ihn aus End Else Begin ShowMessage('Alle Threads wurden ausgeführt'); FreeAndNil (MyThreadList); End; End; Procedure TMainForm.ExecuteAllThreads; Var i : Integer; myThread : TMyThread; Begin {$IFDEF AllowAddingOfThreadsWhileExecuting} If Assigned (MyThreadList) Then Raise Exception.Create('Es sind noch nicht alle Threads abgearbeitet'); {$ELSE} If Not Assigned (MyThreadList) Then MyThreadList := TList.Create; {$ENDIF} For i:=0 to MyThreadCount do Begin myThread := TMyThread.Create (...); // Suspended muss TRUE sein. myThread.OnTerminate := RunNextThread; myThread.FreeOnTerminate := True; // Kannst du so machen oder nicht. MyThreadList.Add(myThread); End; RunNextThread(nil); End; |
Re: Threads nacheinander ausführen
Morgen!
@alzaimar: Genau so habe ich es gemacht, doch das Event OnTerminate wurde nie ausgeführt. Und, btw, wenn den Ihnalt der Execute-Funktion in eine andere Funktion auslagere (zB Download) und diese im Execute mit Synchronize aufrufe, dann wird diese garnicht gestartet. Vielleicht hängt das irgendwie zusammen. |
Re: Threads nacheinander ausführen
Zitat:
|
Re: Threads nacheinander ausführen
Zitat:
|
Re: Threads nacheinander ausführen
du bist auch sicher, daß dein .Execute komplett abgearbeitet wird?
|
Re: Threads nacheinander ausführen
Ja.
|
Re: Threads nacheinander ausführen
Also,
habe noch rausgefunden, dass der Thread immer hängen bleibt, sobald irgendwo "Synchronize" aufgerufen wird. Das verstehe ich nicht. |
Re: Threads nacheinander ausführen
Zitat:
PS: es gibt auch eine TThreadList (grad drüber gestolpert) grad probiert ... bei mir geht's
Delphi-Quellcode:
natürlich in D7 getestet (hast Glück, daß ich das noch drauf hab ^^)
type TMyThread = Class(TThread)
protected procedure execute; override; end; procedure TMyThread.execute; begin asm int 3 end; beep; end; procedure TForm1.RunNextThread(Sender: TObject); begin asm int 3 end; beep; end; procedure TForm1.FormCreate(Sender: TObject); begin asm int 3 end; with TMyThread.Create(true) do begin OnTerminate := RunNextThread; FreeOnTerminate := True; Resume; end; end; Zitat:
Ist mit deinem Hauptthread alles in Ordnung? |
Re: Threads nacheinander ausführen
Vielen Dank. Das schau' ich mir gleich genauer an
Nochmal kurz zum Synchronize-Problem: Wenn ich es einfach weglasse und die Prozedur so aufrufe, dann funktioniert alles prima. Hm. Der Hauptthread läuft ohne Probleme. Ich habe folgenden Aufbau: Das Hauptprogramm wird geladen und sucht nach PlugIns (DLL-Forms). Dann sucht es nach Updates. Werden Updates gefunden und der User möchte diese laden, wird das Plugin "Updates" (auch eine DLL-Form) geladen und darin werden die Updates aufgelistet und daraus auch der UpdateThread gestartet. Hauptanwendung und Update-DLL-Form haben die Unit "Updater" in der Uses-Klausel, in der der Thread und die Update-Prozeduren verfügbar sind. Aber das Funktioniert alles ohne Probleme und ohne MemLeaks (laut FastMM), ausgenommen von einer CriticalSection, die aus der IdHTTP-Komponente kommt. |
Re: Threads nacheinander ausführen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz