Pause in for-Schleife
-
Die Anweisung in der Bedingung wird zwar übersprungen, die (Endlos)Schleife selbst wird aber weiter durchlaufen. Deshalb bleibt auch die CPU-Auslastung oben.
Der vernünftigste Weg ist, die Schleife in einen eigenen Thread auszulagern. Dort kannst du dann Sleep verwenden, ohne die eigentliche Anwendung einzufrieren.
Alternativ könntest evtl. du die for-Schleife in eine eigene Funktion packen, der du Start- und Maximalwert als Parameter übergibst.
In der for-Schleife fragst du wieder deine Bedingung ab. Wenn true (Pause) dann beendest die Schleife und gibst den aktuellen Stand der Zählvariable zurück. Den Wert speicherst du irgendwo ab und übergibst ihn beim nächsten Aufruf der Funktion (UnPause) als neuen Startwert.
-
Application->ProcessMessages(); in der Hauptschleife könnte da weiterhelfen, was die Auslastung der CPU angeht...
-
Danke erstmal!

Ich denk, ich werd morgen mal versuchen, daraus ne eigene Funktion zu machen. Mit Threads hab ich bisher noch nie was gemacht und ich steh leider 'n bisschen unter Zeitdruck.
-kaljinka-
-
Nochmal zum Abspeichern der Zählvariablen... wenn ich die zwischenspeichern möchte, muss ich die Variable dafür notgedrungen global definieren, sonst ist sie nach Beenden der Speicher-Funktion ja wieder weg.
Spricht eigentlich irgendwas dagegen, die Zählvariable selbst gleich global zu definieren? Dann müsst ich sie gar nicht zwischenspeichern.
-kaljinka-
-
Du musst nichts global machen. Geht auch mit Parameter (Referenzübergabe) oder Funktionsrückgabewert.
Globale Variablen sollte man immer vermeiden.
-
HEZ schrieb:
Globale Variablen sollte man immer vermeiden.
Warum?

Wie geht das mit Parametern? Ich muss ja warten, bis der Benutzer die Pause wieder aufhebt. Wo soll ich da den Wert zwischenspeichern wenn nicht global?
-kaljinka-
-
Nun, du hast doch gesagt, du würdest irgendwas in eine Funktion auslagern...
aber gut, da du was von Zeitdruck gesagt hast, mach doch erst mal deine globale Variable. Jetzt muss es erst mal funktionieren.
-
Mir is jetzt was eingefallen. Nachdem ich die Werte für die Laufvariable sowieso ständig in einem Label ausgib, kann ich doch einfach wenn die Pause aufgehoben wird diesen Wert auslesen und wieder in nen Integer verwandeln und meine Funktion aufrufen.
Oder sollt ich das lieber nicht machen? Is des ein ganz schlechter Programmierstil?
Hier mal ein Teil vom Code:
(es geht darum, die Kreiszahl pi stochastisch zu bestimmen)void dart_pi(unsigned long int k, unsigned long int i) { //liefert die pi-Näherungen ab dem i-ten Wurf double x, y; //Koordinaten der Pfeile double curr_pi; //aktuelle pi-Näherung const double factor = 1.0/RAND_MAX; for(;i<=Form1->n; i++) { Application->ProcessMessages(); x = rand()*factor; y = rand()*factor; Form1->DrawCross(x, y); if(x*x + y*y < 1.0) k++; curr_pi = 4.0*k/i; Form1->updateForm(x, y, curr_pi, k, i); if(Form1->pause) { if(Form1->cancel) { Form1->setDefault(); Form1->SpeedButton1->Down = false; return; } return; } } } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButton1Click(TObject *Sender) { //Pause if(SpeedButton1->Down) pause = true; else { pause = false; dart_pi(StrToInt64(Label7->Caption), StrToInt64(Label9->Caption)); } }Und wenn wir schon dabei sind, reicht es, wenn ich randomize() einmal ganz am Anfang, direkt im ButtonClick, aufruf?
-kaljinka-
-
Hallo
Nachdem ich die Werte für die Laufvariable sowieso ständig in einem Label ausgib, kann ich doch einfach wenn die Pause aufgehoben wird diesen Wert auslesen und wieder in nen Integer verwandeln und meine Funktion aufrufen.
Oder sollt ich das lieber nicht machen? Is des ein ganz schlechter Programmierstil?
Wenn du sicherstellst, das in dem Label während des Ablaufes nichts anderes steht, ist es eine gute Lösung. Natürlich benötigt eine Konvertierung von und nach AnsiString immer etwas Rechenleistung, es ist also nicht die effektivste.
Und wenn wir schon dabei sind, reicht es, wenn ich randomize() einmal ganz am Anfang, direkt im ButtonClick, aufruf?
randomize() sollte einmal beim Programmstart aufgerufen werden, also im Konstruktor des MainForms.
bis bald
akari
-
Okay, vielen Dank!

-kaljinka-