Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   2 Threads starten/pausieren... (https://www.delphipraxis.net/196762-2-threads-starten-pausieren.html)

MicMic 17. Jun 2018 19:15

2 Threads starten/pausieren...
 
Hallo,

ich habe derzeit einen Thread den ich folgendermaßen aufrufe.
Code:
Thread1 := TSelfThread.Create(True);
Thread1.FreeOnTerminate := True;
An einer späteren Stelle mache ich dann Thread1.Resume.
In der Execute Prozedur gehe ich eine For-Schleife durch. Wenn die fertig ist, beendet sich der Thread ja automatisch.

Solange der erste Thread läuft (also die For-Schleife noch nicht ferig ist), bräuchte ich eigentlich einen zweiten Thread, der evtl. ab und zu gestartet werden muss. Wenn der zweite Thread gestartet wird, soll sich der erste Thread kurz schlafen legen, also die For-Schleife soll auch pause machen. Wenn der zweite Thread (hier wird es auch eine For-Schleife geben) fertig ist, soll der erste Thread und die For-Schleife weiter laufen. Der zweite Thread muss nie pausiert werden, eher vorzeitig beendet und wieder neu gestartet werden, um hier andere Werte (von - bis) bei der For-Schleife durchzugehen. Wenn der erste Thread (also die For-Schleife) komplett fertig ist, muss der zweiter Thread nicht mehr gestartet werden.

Kann man das realisieren?

Michael

jaenicke 17. Jun 2018 19:46

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von MicMic (Beitrag 1405013)
Wenn der zweite Thread gestartet wird, soll sich der erste Thread kurz schlafen legen, also die For-Schleife soll auch pause machen. Wenn der zweite Thread (hier wird es auch eine For-Schleife geben) fertig ist, soll der erste Thread und die For-Schleife weiter laufen.

Die Kommunikation könnte z.B. per TEvent passieren, aber ich frage mich warum der erste Thread nicht auch diese Aufgabe übernimmt, wenn er seine Aufgabe derweil ohnehin nicht fortsetzen soll. Wer startet denn den zweiten Thread? Der erste Thread?

MicMic 17. Jun 2018 20:09

AW: 2 Threads starten/pausieren...
 
Also ich möchte im Thread wenige Prüfungen machen, damit er schnell bleibt.
Ich habe im Thread beispielsweise eine For-Schleife von 0-5000, in der ein Programmcode abgearbeitet werden muss. Für die aktuelle For-Zahl kann ich jedenfalls prüfen, ob der Programmcode auch wirklich abgearbeitet werden muss (also er müsste eigentlich nicht beendet werden), denn je nach Benutzeraktion muss evtl. vorzeitig 250-500 oder 3000-4000 von der For-Schleife verarbeitet werden. Ich muss eigentlich im Hauptprogramm je nach Benutzeraktion zwei Variablen "von" und "bis" festlegen, die etwas Zeit benötigen und dachte deshalb an einen zweiten Thread.

Michael

MicMic 17. Jun 2018 20:34

AW: 2 Threads starten/pausieren...
 
Ich habe mir gerade folgendes für die Execute überlegt (ungetestet).
Müsste nur dann im Hauptprogramm wenn erforderlich die Variablen "von", "bis" und "check" setzen.
Während meine 5000 (hier jetzt repeat/until) abgearbeitet werden, wird ja geprüft ob vorzeitig ein anderer Zahlen-Abschnitt gebraucht wird. Man muss nur schauen, dass man keine i-Zahl auslässt und eigentlich schon abgearbeitete nicht mehr erneut abgearbeitet werden.

Code:
repeat

 i = i +1;
 if check = true then
 begin
  if isave = -1 then
  begin
   isave = i;
   i = von;
  end;
 end;

 daten[i]...

 if check = true then
 begin
  if i = bis then
  begin
   i := isave;
   check := false;
  end;
 end;

 if i=5001 then ok := true;

until ok=true
Kann ich die Variablen "von", "bis" und "check" einfach setzen?

So vielleicht:
Code:
type
 TThread1 = class(TThread)
 private
 von,bis : integer;
 check : boolean;
 public
 procedure Execute; override;
end;
Und im Hauptprogramm, während der Thread läuft dann irgendwo wenn gewünscht einfach...
Code:
 Thread1.von := 50;
 Thread1.bis := 100;
 Thread1.check := true;
Michael

Dennis07 17. Jun 2018 21:18

AW: 2 Threads starten/pausieren...
 
Und wieso benutzt du dann nicht einfach wei unterschiedliche Routinen für den selben Thread? So bekommst du es dann ohne Überpfüfungen hin...

Delphi-Quellcode:
type

TMyThread = class(TThread)
private
  procedure First;
  procedure Second;
protected
  ExecutionRoutine: TProcedure;
public
  procedure Execute; override;
end;

procedure TMyThread.Execute; override;
begin
  while not Terminated do
  begin
    ExecutionRoutine;
  end;
end;

procedure TMyThread.First;
begin
  //Falls (nicht B), unterbreche für zweite Routine
  if not B then
  begin
    ExecutionRoutine := Second;
  end;
end;

procedure TMyThread.Second;
begin
  //Nach Beendigung wieder erste Routine
  ExecutionRoutine := First;
end;
EDIT: Kannst du natürlich auch mit anonymen Methoden machen, falls dein Delphi das unterstützt. Hab ich allerdings weggelassen, denn ansonsten könntest du ja auch direkt
Delphi-Quellcode:
TThread.CreateAnonymousThread(...)
nehmen.

jaenicke 17. Jun 2018 21:23

AW: 2 Threads starten/pausieren...
 
Das würde ich anders lösen. Ich würde das ganze in Pakete aufteilen, die abzuarbeiten sind. Die Größe der Pakete hängt davon ab wie lange es dauert diese zu bearbeiten. Auf die Weise kannst du schnell unterbrechen, auch wenn immer das komplette Paket bearbeitet wird.

Die einzelnen Pakete kannst du dann in eine Queue packen, der Thread holt sich dann jeweils immer das nächste Paket heraus. Die Queue muss natürlich threadsicher sein. Von außen kannst du nun einfach Einfluss auf die Abarbeitung der Pakete nehmen, z.B. indem du ein Paket an Platz eins setzt und so weiter. Auf die Weise kannst du einzelne Pakete priorisieren oder nach hinten schieben.

Dennis07 18. Jun 2018 03:00

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von jaenicke (Beitrag 1405024)
Das würde ich anders lösen. Ich würde das ganze in Pakete aufteilen, die abzuarbeiten sind. Die Größe der Pakete hängt davon ab wie lange es dauert diese zu bearbeiten. Auf die Weise kannst du schnell unterbrechen, auch wenn immer das komplette Paket bearbeitet wird.

Die einzelnen Pakete kannst du dann in eine Queue packen, der Thread holt sich dann jeweils immer das nächste Paket heraus. Die Queue muss natürlich threadsicher sein. Von außen kannst du nun einfach Einfluss auf die Abarbeitung der Pakete nehmen, z.B. indem du ein Paket an Platz eins setzt und so weiter. Auf die Weise kannst du einzelne Pakete priorisieren oder nach hinten schieben.

Jo, so ließe sich das natürlich auch lösen. Wenngleich sich so eine Lösung wohl eher bei komplexeren Szenarien wirklich auszahlen würde. Bei zwei Paketen braucht man noch keine Queue, finde ich.

MicMic 18. Jun 2018 09:25

AW: 2 Threads starten/pausieren...
 
Danke für die Vorschläge.
Noch etwas schwer für mich... mit first/second oder Queue-Dingsbumbs :)

Meine eigene Überlegung mit dem Code den ich hier aufgeschrieben habe, ist auch nicht so einfach. Da muss man aufpassen denn sobald die Variablen außerhalb des Threads gesetzt werden, werden diese ja auch im Thread übernommen. Da kommt es dann drauf an, wo der Thread gerade die Zeile verarbeitet. Dennoch habe ich damit weiter probiert und habe es jetzt so:

Code:
 iV := 0;              // Originale Start-Zahl (immer 0)
 iB := Length(FDR)-1;  // Originale End-Zahl (z.B. bis 5000)
 i := 0;               // Ab 0 beginnen
 userpos := false;     // False = normaler Durchgang

 repeat

  daten[i]...

  i := i + 1;

  if ucheck = true then
  begin
   iv := i;
   i := uiv;
   ib := uib;
   if ib > Length(FDR)-1 then ib := Length(FDR)-1;
   ucheck := false;
   userpos := true;
  end;

  if userpos = true then
  begin
   if i>= ib then
   begin
    i := iv;
    ib := Length(FDR)-1;
    userpos := false;
   end;
  end;

 until i >= ib;
Außerhalb des Thread setzte ich dann nach Benuteraktion:
Code:
 Thread1.uiv := neue_start_zahl; // z.B. 200
 Thread1.uib := neue_end_zahl;  // z.B. 1000
 Thread1.ucheck := true;
So geht es einigermaßen aber der Thread wird nicht beendet, wenn der Benutzer ständig Aktionen durchführt. Da muss ich noch rumbasteln. Aber so im Ganzen ist es wohl auch nicht optimal, wenn ich gerade drüber nachdenke.

Eigentlich soll es so sein:
Der Thread soll halt ganz normal von 0-5000 (als Beispiel) die Schleife verarbeiten. Kommt der Benutzer und will (200-1000) dann sollen diese erster verarbeitet werden. Sind diese aber schon durch von der normalen Schleife 0-5000 dann müssen diese 200-1000 nicht verarbeitet werden. Der Benutzer kann jedenfalls zwischen dieser Zeit 200-1000 wieder eine neue Aktion durchführen und will 3000-4000 haben, diese dann aktuell verarbeitet werden sollen, solange diese nicht schon von der normalen Schleife verarbeitet wurden. Ich hoffe das ist verständlich :)


Zum Glück sind meine "daten[i]..." Sachen (es ist ein Record) so aufgebaut.
Code:
 nr := daten[i].nummer;
 If nr = -1 Then
 Begin
  // ... Daten werden verarbeitet, gesetzt, gespeichert usw.
  // und das kostet etwas mehr zeit (mal 1 sek, mal 5 sek. je nach Inhalt, der immer anders sein kann)
  daten[i].nummer := zahl größer -1;
 End
Also es ist nicht so ganz schlimm, wenn die Schleifenzahl schon mal genutzt wurde.
Ich kenne mich noch nicht so aus mit den Threads und was man alles so damit machen kann. Deswegen denke ich, es wäre der beste Weg, man hat einen Thread für die 0-5000 und ein weiteren Thread für die Benutzeraktion. Wenn der Benutzer-Thread ausgeführt werden soll, soll der 0-5000 Thread pause machen. Das könnte man ja so realisieren, dass die Schleifenzahl nicht weiter hochzählt. Ist der Benutzer-Thread fertig, dann wird die Schleifenzahl vom normalen 0-5000 Thread wieder weiter hochgezählt. Ob nun bei dem einem Thread oder beim anderen die daten[i]... schon verarbeitet wurden oder nicht, wäre ja nicht so schlimm, da ich dieses ja mit "nr := daten[i].nummer" auf "-1" prüfe.

Ich habe schon gelesen, dass es nicht so optimal ist, wenn man Threads pausieren lässt und wieder startet. Wie gesagt, bei dem normalen 0-5000 Thread könnte ich ja zum Pausieren die Schleifenzahl nicht hochzählen lassen und ein Benutzer-Thread erstellen. Ist der Benutzer-Thread fertig, wird er einfach freigegeben. Wenn der normale 0-5000 Thread durch ist und beendet wurde, muss kein Benutzer-Thread mehr erstellt werden (da ja alles von den 0-5000 durch ist). So meine Überlegungen :)

Michael

Schokohase 18. Jun 2018 10:31

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von MicMic (Beitrag 1405049)
Eigentlich soll es so sein:
Der Thread soll halt ganz normal von 0-5000 (als Beispiel) die Schleife verarbeiten. Kommt der Benutzer und will (200-1000) dann sollen diese erster verarbeitet werden.

Wenn du das sagst - was immer du auch damit meinst
Zitat:

Zitat von MicMic (Beitrag 1405049)
Sind diese aber schon durch von der normalen Schleife 0-5000 dann müssen diese 200-1000 nicht verarbeitet werden. Der Benutzer kann jedenfalls zwischen dieser Zeit 200-1000 wieder eine neue Aktion durchführen und will 3000-4000 haben, diese dann aktuell verarbeitet werden sollen,

Meister Joda?
Zitat:

Zitat von MicMic (Beitrag 1405049)
solange diese nicht schon von der normalen Schleife verarbeitet wurden. Ich hoffe das ist verständlich :)

Nein.

MicMic 18. Jun 2018 10:47

AW: 2 Threads starten/pausieren...
 
Ich habe es jetzt so.
Den 0-5000 Thread erstelle in meinem OnCreate von der Form und setzte "Thread1.FreeOnTerminate := true;".
"Thread1.Start" kommt an einer anderen Stelle zum Einsatz.
Der geht nun ganz normal durch (mit Repeat/Until-Schleife) und wird nach beenden freigegeben.

Der wird auch nicht pausiert. Aber das würde ich noch gerne einbauen. Daran versuche ich mich gleich.

Der Benutzer-Thread erstelle ich so:
Code:
 if Thread1.Terminated = False Then
 Begin
  UserThread.free;
  UserThread := TUserThread.Create(true);
  UserThread.FreeOnTerminate := false;
  UserThread.iv := UserStartZahl;
  UserThread.ib := UserEndZahl;
  UserThread.Start;
 End;
Solange der Thread1 (0-5000 Thread) läuft, kann ein UserThread erstellt werden.
UserThread.free brauche ich ja hier nicht prüfen oder? Wenn gerade ein UserThread läuft, wird durch "UserThread.free" dieser ja beendet und freigegeben. Wenn keiner läuft, geht "UserThread.free" ja auch, also es machts nichts, wenn keiner freigegeben werden muss. In der Execute von UserThread läuft dann eine For-Schleife (i := iv to ib) ab.

So funktioniert es jedenfalls.

Michael

jaenicke 18. Jun 2018 10:57

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von MicMic (Beitrag 1405062)
Den 0-5000 Thread erstelle in meinem OnCreate von der Form und setzte "Thread1.FreeOnTerminate := true;".
"Thread1.Start" kommt an einer anderen Stelle zum Einsatz.

Wenn du FreeOnTerminate setzt, darfst du den TThread nicht in eine Variable (Thread1) speichern. Denn da du nicht weißt wann dieser freigegeben wird, darfst du auch nicht mehr darauf zugreifen.

Wenn du den Thread später noch ansprechen möchtest, darfst du FreeOnTerminate nicht setzen.

MicMic 18. Jun 2018 11:09

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von jaenicke (Beitrag 1405065)
Zitat:

Zitat von MicMic (Beitrag 1405062)
Den 0-5000 Thread erstelle in meinem OnCreate von der Form und setzte "Thread1.FreeOnTerminate := true;".
"Thread1.Start" kommt an einer anderen Stelle zum Einsatz.

Wenn du FreeOnTerminate setzt, darfst du den TThread nicht in eine Variable (Thread1) speichern. Denn da du nicht weißt wann dieser freigegeben wird, darfst du auch nicht mehr darauf zugreifen.

Wenn du den Thread später noch ansprechen möchtest, darfst du FreeOnTerminate nicht setzen.

Meinst du, ich darf nicht mit "If Thread1.Terminated = False Then" prüfen, ob der noch läuft? Ich könnte ja eine Globale Variable setzen wenn der Thread1 fertig ist, also die Repeat/Until Schleife fertig ist. (Thread1fertig=true). So wäre es besser oder?

sko1 19. Jun 2018 07:51

AW: 2 Threads starten/pausieren...
 
Zitat:

Wenn der zweite Thread gestartet wird, soll sich der erste Thread kurz schlafen legen, also die For-Schleife soll auch pause machen
Ich verstehe diesen Ansatz nicht ganz, das widerspricht doch dem Sinn eines Threads!
Denn der läuft im Hintergrund und blockiert damit den Haupt-Thread nicht mehr mit zeitaufwändigen Schleifen.
Warum soll der nun pausiert werden wenn ein weiterer Thread gestartet wird?

Ciao
Stefan

OlafSt 19. Jun 2018 08:17

AW: 2 Threads starten/pausieren...
 
Warum so kompliziert.

Gib doch den einzelnen Datenelementen ein Flag "Hab ich schon" mit. Das wird gesetzt, sobald der Thread das Element verarbeitet hat. Außerdem gibst dem Thread mit, von wo bis wo er arbeiten soll (Standard 0 bis Ende). Dann lass den Thread laufen.

Will der User nun plötzlich die Elemente 200-800 verarbeitet haben, gibst dem Thread einfach diese beiden Werte an. Der Thread verarbeitet den laufenden datensatz noch ab und kümmert sich dann um die vorgegebene Range. Durch das markieren mit "Hab ich schon" werden die ja auch kein zweites Mal angefaßt. Hat der Thread seine Range durch (also 200-800 abgearbeitet), gehts einfach wieder von vorn los mit 0-Ende. Durch das "Hab ich schon" arbeitet er dann von ganz allein die ganze Arie ab - selbst wenn der User plötzlich noch 1000-1600 sehen will.

Alles in einem Thread, ohne kompliziertes Anhalten/Weiterlaufen/Synchronisieren.

jaenicke 19. Jun 2018 12:24

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von OlafSt (Beitrag 1405180)
Gib doch den einzelnen Datenelementen ein Flag "Hab ich schon" mit.

Das ist ja genau die Idee hinter der von mir vorgeschlagenen Queue, nur dass man damit die abzuarbeitenden Daten besser steuern kann als mit ein paar Flags.

Es kommt natürlich immer darauf an was man genau braucht, das kann man von außen nicht genau sagen.

Dennis07 19. Jun 2018 12:27

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von jaenicke (Beitrag 1405065)
Wenn du FreeOnTerminate setzt, darfst du den TThread nicht in eine Variable (Thread1) speichern. Denn da du nicht weißt wann dieser freigegeben wird, darfst du auch nicht mehr darauf zugreifen.

Wenn du den Thread später noch ansprechen möchtest, darfst du FreeOnTerminate nicht setzen.

Wiebitte? Wie soll er denn bitte erzeugen,
Delphi-Quellcode:
FreeOnTerminate
setzen und starten, ohne den Thread zwischenzuspeichern? Das ginge, wenn überhaupt, nur noch entweder im
Delphi-Quellcode:
Execute
(was unsauber wäre) oder mit einem
Delphi-Quellcode:
with
(ebenso). Prinzipiell kannst du ihn ja in so vielen Variablen speichern, wie du lustig bist. Du darfst/solltest nur nach dem Starten der Ausführung nicht mehr auf mehr auf das Objekt ohne
Delphi-Quellcode:
try
zugreifen, sofern
Delphi-Quellcode:
FreeOnTerminate
gesetzt wurde. Davor jedoch kannst du so viel an dem Ding rumspielen wie es dir danach verlangt.

himitsu 19. Jun 2018 13:23

AW: 2 Threads starten/pausieren...
 
Sorry, aber TRY ...

Man darf NIEMALS wieder darauf zugreifen, sobald der Thread einmal gestartet wurde, egal wo.

Ausnahme: Der Thread setzt diese Variable auf NIL, bevor er freigegeben wird.
Zugriffe auf diese Variable aber auch nur noch abgesichert, also z.B. innerhalb einer CriticalSection.

jaenicke 19. Jun 2018 13:52

AW: 2 Threads starten/pausieren...
 
Zitat:

Zitat von Dennis07 (Beitrag 1405225)
Wiebitte? Wie soll er denn bitte erzeugen,
Delphi-Quellcode:
FreeOnTerminate
setzen und starten, ohne den Thread zwischenzuspeichern?

Warum sollte man denn einen solchen run-and-forget Thread suspended erzeugen?!? Der bekommt alle notwendigen Parameter und legt sofort los.

(Ich sehe generell keinen Sinn darin suspended zu erzeugen, egal was für ein Thread das ist. Entweder man braucht den Thread jetzt, dann kann er auch gleich loslegen oder man braucht ihn noch nicht, dann braucht man ihn auch noch nicht erzeugen.)

Aber für genau diesen Zweck, ihn nach dem Erzeugen zu starten, kann man eine solche Variable natürlich benutzen. Aber eben danach nicht mehr.

MicMic 22. Jun 2018 00:17

AW: 2 Threads starten/pausieren...
 
Hallo,
da sind wir wohl etwas durcheinander gekommen. Oder ich :)
Also ich habe einen Thread der mit einer Repeat/Until-Schleife eine reihe von Zahlen durchgeht. Beispielsweise 0-5000. Den erstelle ich inaktiv in meinem Form-Create und mit „FreeOnTerminate = True“ (damit er sich selbst freigibt, wenn fertig). Inzwischen sind es zwei Threads davon, weil es auch zwei Datenhälften gibt, die wechselnd verarbeiten werden sollen. Passt so besser. Die beiden Threads nenne ich jetzt mal die Hauptthreads. Sie werden an einer passenden Stelle im Programm gestartet und kommen auch nur 1x zum starten.

Nun greift beispielsweise der Benutzer während die beiden Hauptthreads laufen ein und es wird dann von einer Datenhälfte ein Paket benötigt. (z.b. 3000-4000). Damit alles schneller geht, sollen nun die beiden Hauptthreads Pause machen.

Ich habe das nun so gelöst, dass es wiederum zwei weitere Threads gibt, die für die Aktion des Benutzers zuständig ist. Die nenne ich jetzt mal UserThreads. Die sind jedenfalls noch nicht erstellt, sondern werden erst erstellt, wenn der Benutzer die Aktion wählt, sprich das Paket von 3000-4000 als erstes geladen werden soll. Passiert so etwas, dann wird erst mal geprüft ob der Hauptthread für die richtige Datenhälfte überhaupt noch läuft. Ist er nämlich fertig, dann brauch man auch kein Userthread mehr. Diese Prüfung hatte ich mit einem „if .Terminated“ geprüft aber da war ich mir nicht so sicher, da diese Hauptthreads sich selber freigeben und ob man dann mit diesem „Termitated“ darauf noch zugreifen darf, ist mir nicht so ganz klar. Es geht zwar aber ich habe lieber eine globale Variable dafür eingesetzt. Die Benutzer-Aktion (1 von 2) schaut jedenfalls so aus:
Code:
If HThread1Finish = False Then
Begin
  UserThread1.free;
  UserThread1 := TUserThread1.Create(true);
  UserThread1.FreeOnTerminate := false;
  Userthread1.Priority := tpTimeCritical;
  UserThread1.iv := startzahl // z.B. 3000
  UserThread1.ib := enddzahl // z.B. 4000
  UserThread1.Start;
End;
Also beim ersten Mal ist ein „.free“ irgendwie nutzlos aber für weitere Aktionen ist hier dafür der beste Platz. Es macht wohl nichts aus, wenn ein Thread freigegeben werden soll, der gar nicht existiert. Bei einer 2. Aktion vom Benutzer wird er jedenfalls freigegeben und darauf wieder erstellt. So starte ich jedenfalls meine UserThreads. Hier bei den UserThreads habe ich kein „ FreeOnTerminate=True“ gewählt, da sie auch durch eine neue Aktion vom Benutzer abgebrochen werden sollen. Wegen „Priority“… ich muss da noch mal schauen ob das was bringt. In der Execute von UserThread1 (auch im anderen UserThread2) setze ich noch eine globale Varibale „ThreadsPause“ auf „True“, damit die beiden Hauptthreads nicht in der Repeat/Until Schleife weiter hoch zählen. Ist UserThread1 fertig, wird die Variable „ThreadsPause“ wieder auf „False“ gesetzt und die Hauptthreads laufen weiter bzw. sie laufen ja die ganze Zeit aber die Zählervariable dort, wird wieder weiter hochgezählt. Nach der letzten Benutzer-Aktion bleiben ja immer noch zwei UserThreads im Speicher. In meinem Form Destroy gebe ich dann noch die beiden UserThreads frei. So funktioniert das ganze eigentlich recht gut. Natürlich habe ich bei meinen Daten auch ein „hab ich schon“ also als „User[zählervariable].Nummer“ festgelegt. Die Nummer steht auf „-1“ und wenn die Daten verarbeitet wurden, wird diese auf einen anderen Wert (größer als -1) festgelegt. Also wenn der Benutzer ein Paket von 3000-4000 haben will und der Hauptthread ist hier noch nicht angekommen (wird später auf diesen Zahlenbereich kommen), dann ist dies nicht so schlimm. Ich prüfe ja auf den Wert „-1“ und nur dann kommen die rechenintensiven Befehle zum Einsatz. Das Ganze wollte ich ja nur mit einem Thread lösen aber die ganzen Variablen zu setzen (außerhalb) sind schwer im Thread zu prüfen, da der Thread ja läuft und immer wo anders ist, im Execute Bereich (mal Zeile 4, dann 7 und mal Zeile 13). Da macht es sich schwer, ein 0-5000 abzubrechen, dann 3000-4000 durchzugehen, wobei durch einen neuen Abbruch das ganze nur bis 3580 gegangen ist, weil der Benutzer ja schon wieder neue 200-1200 haben will. Dies mit Variablen so zu prüfen, dass sich nichts in die quere kommt, ist echt schwer. Bestimmt gibt es da Lösungen/Befehle etc. denn es gibt ja nicht nur „Execute“. Es sind ja auch meine ersten Erfahrungen mit Threads und so wie ich es jetzt habe, gefällt es mir natürlich dann… weils halt geht :)

Ich hoffe es ist nun verständlich wie ich so meine Threads einsetze und zu welchem Zweck. Ich fülle Daten Records mit Werten, die dann zur Ansicht kommen. 2-3 Befehle (um mein Daten Record zu füllen) kosten dann etwas Zeit und damit der Benutzer auf diese Ansicht nicht warten muss, brauche ich dann diese Threads… die sicherlich besser gelöst werden können aber ich halt noch kein Durchblick dazu habe. :)

Michael

Rollo62 22. Jun 2018 08:44

AW: 2 Threads starten/pausieren...
 
Klingt kompliziert, habs jetzt nicht komplett nachvollzogen was du machst ...

Ich würde einfach zwei Threads über Events steuerbar machen, so in der Art, aber die Setter/Getter der Zugriffs-Properties noch sicherheitshalber in TCriticalSections verpacken.
Dann könntest du die Threads intern immer laufen lassen, und ja nach Guste über die Events stillegen oder freischalten.

Dann braucht man kein "Terminate" (nur am Programende, und keine globalen Variablen.

Rollo


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:45 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz