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 - 2do
 begin

  while not Terminated do begin // KORREKT, wenn diese Zeile entfernt wird /////////////////////////////////////////////////////////
  showmessage(IntToStr(G.RowCount) + ' - 2 ..... now: ' + IntToStr(ii));
  Upload(ii, G.Cells[0,ii], G.Cells[1,ii], G.Cells[2,ii]);

  end// KORREKT, wenn diese Zeile entfernt wird /////////////////////////////////////////////////////////
 end;
end;


Narses - Mo 12.03.12 23:59

Moin!

Zwei klassische Fehler: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 - 2do
  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 user profile iconNarses 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 - 2do
  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 - 2do
  begin
  if Terminated then Break;
  //do anything...
  end;
end;