![]() |
Thread - Problem
Ich führe eine Berechnung in einem Thread aus, die ein außerhalb des Thread definiertes Array bearbeitet, und zwar so: Ist eine Teil-Berechnung fertig, rufe ich in der OnTerminate-Ereignisprozedur des Thread eine Prozedur im Hauptthread auf, die
1. Die berechneten Daten aus dem Array auswertet und in eine Datei speichert 2. den gleichen Thread mit neuen Berechnungsparametern erneut startet wodurch sich ein Berechnungskreislauf ergibt, so dass die Anwendung ständig beschäftigt ist. Es passiert nun nach einigen Stunden fehlerfreien Ablaufs, dass das Programm ohne Fehlermeldung stehenbleibt, anscheinend, weil die max. von Windows verwaltbare Threadanzahl überschritten wurde. Es lässt sich jedenfalls in diesem Zustand keine andere Anwendung mehr starten. Jetzt habe ich von m_junglas im Thema "Programmabsturz! Warum?" gelernt, dass der Thread nach OnTerminate keineswegs schon beendet ist und man keinen Einfluss darauf hat, wann Windows nun gedenkt, ihn wirklich zu beenden. Dass das wirklich so ist, sieht man auch, wenn man in der OnTerminate-Ereignisprozedur "WaitFor" verwendet - Das Programm steht dann ab da und wartet quasi auf sich selbst. Wenn das also so ist, ist OnTerminate für mich unbrauchbar, denn ich will ja den Thread quasi aus der OnTerminate-Ereignisprozedur heraus neu starten (eigentlich ein Wunder, dass das Programm erst nach Stunden, d.h. nach einigen Tausend Berechnungs-Zyklen, stehenbleibt). Also hier beißt sich die Katze in den Schwanz, denn in der OnTerminate-Ereignisprozedur darf ich den Thread auch nicht beenden, wie schon m_junglas feststellte, andererseits will ich den Hauptthread auch nicht ständig prüfen lassen, ob der Thread noch läuft, so ähnlich wie NicoDE im Thema "Unit in Thread packen?!" vorschlug...: while not CalculationTerminated do Application.ProcessMessages(); // Solange die GUI reagieren lassen ...denn ich brauche den Prozessor ja für die Berechnung. Ich brauche also, im Gegensatz zu OnTerminate, das Ereignis, wann der Thread WIRKLICH von Windows beendet wurde. Delphi erkennt das ja anscheinend auch, wie man im Debugfenster "Threads" sehen kann. Weiß einer, wie man's macht? :gruebel: Zusatzfrage: Wie ändere ich eigentlich die Priorität des Haupt-Thread einer Anwendung? |
Re: Thread - Problem
Moin engel,
Zitat:
While BerechnungOffen do begin Thread erstellen Thread mit Daten füttern Thread starten, und auf Ende warten. Thread freigeben. end; Zitat:
[EDIT] Zitat:
[/EDIT] |
Re: Thread - Problem
Zitat:
Es muss doch was Besseres geben. |
Re: Thread - Problem
Wieso erstellst Du einen Thread jedesmal neu?
Schreibe dir einen 'Workerthread', der im Hintergrund auf Jobs wartet. Sobald ein Job ankommt, wird er bearbeitet und anschließend geht das Spiel von vorne los. Falls zwischenzeitlich ein neuer Job angekommen ist, wird der gleich verarbeitet. So ist das sauber. Und ein Job ist einfach eine Teilaufgabe. Ich vermute, das Du im OnTerminate den Thread nicht einfach neu anstoßen kannst. Vielleicht kommt Windows da durcheinander. |
Re: Thread - Problem
Hi,
So sollte es mit weniger CPU last gehen:
Delphi-Quellcode:
Hierbei dient BerechnungOffen nur zum Beenden der gesammten Berechnung.While BerechnungOffen do begin //Thread erstellen //Thread mit Daten füttern repeat dwWaitResult := WaitforSingleObject(Thread.Handle, 200); if dwWaitResult <> WAIT_OBJECT_0 then begin Application.ProcessMessages; end; until dwWaitResult = WAIT_OBJECT_0; //Thread freigeben end Du wirst ohne eine Steuerung auserhalb des Arbeitenden Threads nicht auskommen. Edit : oder so wie alzaimar es vorgeschlagen hat mit Jobs dafür giebts hier auch irgendwo einen Code. |
Re: Thread - Problem
Zitat:
Was ich weiß ist, dass die Execute-Methode des Threads nur einmal ausgeführt werden kann (oder stimmt das nicht?). Dann müsste die Execute-Methode ja eine Endlosschleife enthalten? Wie programmiert man dieses "auf einen Job warten"? :roll: Oder kann man FreeOnTerminate auf False setzen und den Thread etwa mehrmals hintereinander mit Resume starten? |
Re: Thread - Problem
|
Re: Thread - Problem
Zitat:
Danke, das mit den Job's probier ich mal aus. Aber die Lösung meines Problems ist einfach nur: In der OnTerminate-Ereignisprozedur den Thread auf NIL setzen (sonst nix)! Matthias :angel2: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:23 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