Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Variable im Thread zählt nicht hoch
whitef - Mo 12.03.12 23:39
Titel: Variable im Thread zählt nicht hoch
hi,
ich hab mich mal ein wenig mit Threads auseinandergesetzt. Es klappt alles soweit ganz gut.
Bis ich den "Abbrechen" Button einbauen wollte. Im Thread erstell ich eine TIdFTP.
"ii" variiert hier: 0 bis x (Für jedes "ii" wird ein Upload gestartet)
Mittels showmessage überprüfe ich mein "ii". Leider wird mir "ii" immer mit dem Wert "0" ausgegeben.
Sobald ich allerdings die kommentierten Absätze entferne, wird mir "ii" wieder mit dem korrekten Wert ausgegeben.
wie kann ich dass denn umgehen?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TMyOwnThread.Execute; var ii, i : Integer; begin ... for ii := 0 to (G.RowCount - 2) do begin
while not Terminated do begin showmessage(IntToStr(G.RowCount) + ' - 2 ..... now: ' + IntToStr(ii)); Upload(ii, G.Cells[0,ii], G.Cells[1,ii], G.Cells[2,ii]);
end; end; end; |
Narses - Mo 12.03.12 23:59
Moin!
Zwei klassische Fehler:
- du greifst unsynchronisiert auf VCL-Controls zu (das mag ja vielleicht lesend noch gehen, dann müssen die Controls aber mindestens disabled sein!)
- ShowMessage in einem Thread ist phöse! Ganz phöse! :mahn: Was da raus kommt, ist undefiniert. Gib deine Logausgaben synchronisiert z.B. in ein Memo aus
Ansonsten kann man bei dem kleinen Stück Code nicht mehr sagen. :nixweiss:
cu
Narses
jaenicke - Di 13.03.12 07:39
Dir ist offensichtlich nicht ganz klar was du da eigentlich mit der inneren Schleife tust. Anders kann ich mir dieses Konstrukt nicht erklären...
Mal aufs Wesentliche reduziert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TMyOwnThread.Execute; var ii, i : Integer; begin for ii := 0 to (G.RowCount - 2) do begin while not Terminated do begin end; end; end; |
Die innere Schleife läuft nun so lange bis der Thread beendet wurde. Sprich solange das nicht der Fall ist, bleibt die for-Schleife beim ersten Durchlauf mit dem Wert 0. Die innere Schleife wartet dann bis der Thread beendet wurde. Es wird also immer wieder der Code für ii = 0 ausgeführt.
Gedacht ist diese while-Schleife dafür, dass du in einem Thread etwas machst, bis er beendet wird. Dann musst du diese Schleife aber als äußerste Schleife benutzen, damit die for-Schleife auch immer komplett durchlaufen wird. (Wenn das denn überhaupt das ist was du willst... also das ganze mehrfach ausführen... sonst kannst du dir die while-Schleife sparen. Und ich denke mal das ist es was du willst.)
Die von
Narses genannten Punkte gelten natürlich außerdem und sind auch der Grund weshalb es auch ohne die nicht benötigte while-Schleife nicht richtig geht.
whitef - Di 13.03.12 22:32
@Narses
Vielen Dank soweit.
-Mit den showmessages hast du natürlich recht, es kommen vereinzelnd merkwürdige ausgaben in diesen. Ich hab sie lediglich zur direkten überprüfung. Nach Erstellung werden diese entfernt.
-Dieses G.Rowcount wurde erst im Thread created (StringGrid). Es wird lediglich am anfang von "thread.execute" mit der StringGrid von der Form gefüllt, damit wenigstens die for-schleife nicht direkt darauf zugreift. (synchronise ist sinnvoller, werde ich dann noch korrigieren.)
@jaenicke
jetzt ist es mir gekommen^^
dieses "while not Terminated do" hab ich tatsächlich fehlinterpretiert.
Aber ich weiss momentan leider nicht wie ich es hier verwenden muss, um das hochladen der restlichen "ii"'s zu verhindern (>"Abbrechen"); könntest du mir das etwas näher erläutern?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TMyOwnThread.Execute; var ii, i : Integer; begin for ii := 0 to (G.RowCount - 2) do begin while not Terminated do begin end; end; end; |
für jedes "ii", führe folgendes aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TMyOwnThread.Upload(Count:Integer; Full:String; FilePath:String; FileName:String); var x, z : Integer; s, ss, sss, addon, Path1, Path2, Result1 : String; List : TStrings; begin ... FTP_Thread.Put(Full, DEST1 + FilePath + FileName, True); Form1.Log.Lines.Add(FormatDateTime('yy-mm-dd', now) + ' - ' + FormatDateTime('hh:nn:ss', now) + ': ' + 'Target: ' + DEST1 + FilePath + FileName); Form1.Log.Lines.Add('>>> NEXT FILE--------------'); end; |
whitef - Mi 14.03.12 20:54
so gelöst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TMyOwnThread.Execute; var ii, i : Integer; begin for ii := 0 to (G.RowCount - 2) do begin if Terminated then Break; end; end; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!