![]() |
For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler.
im folgenden Bsp. zählt die (var THI :integer) mehr als angegeben und lässt eine Zählung aus. Also THI = 0,1,2,3,4,5,6,7,8,9,10,12 << Ich dachte hier überschneidet sich irgendwas und wollte dies mit tempTHI := THI; //thi integer für task separieren. doch auch hier wird die 11 ausgelassen und mit 12 weitergemacht. - Wieso zählt hier ein festes integer Array weiter als angegeben ? - continue hab ich hier ausgesetzt , ohne erfolg
Delphi-Quellcode:
TTasks = Array [0..11] of ITask; TTaskActiveArray = Array [0..11] of integer; var Tasks:TTasks; TaskActiveAr:TTaskActiveArray;
Delphi-Quellcode:
var THI:integer;
anyTaskIsRunning := 1; for THI := 0 to 11 do begin log(1,'read_ALL_data->TaskActiveAr['+ inttostr(THI) +'] = ' + inttostr( TaskActiveAr[THI] ) + ' begin'); //thread erstellen Tasks[THI] := TTask.Create( procedure () var indI, tempTHI, is_own_number, byte : integer; tempS, tempS1, tempS2, tempS3, tempS4:string; begin tempTHI := THI; //thi integer für task separieren //task I/O ob task running (0 fetrig, 1 running, 2 soll, 3 nicht gebraucht) TaskActiveAr[tempTHI] := 1; log(7,'read_ALL_data->TASK TaskActiveAr['+ inttostr(tempTHI) +'] = ' + inttostr( TaskActiveAr[tempTHI] ) + ' begin'); log(0,'tempTHI / THI = ' + inttostr( tempTHI ) + ' / ' + inttostr( THI ) ); //thread geht komplette liste durch und bearbeitet nur seine threadnummer for indI := 0 to box.RowCount - 1 do begin tempI := -1; is_own_number := 0; //threadnummer auslesen und in integer wandeln wenn möglich if ( true = IsStringAInteger( box.Cells[ 9, indI] )) then begin tempI := strtoint(box.Cells[ 9, indI]); //log(0,'IsStringAInteger --> line('+ inttostr( indI ) +') = tempI : ' + inttostr( tempI ) ); end else begin //log(0,'line (' + inttostr( tempI ) + ') IsStringAInteger -> line('+ inttostr( indI ) +') = false --> continue '); //wenn kein integer dann überspringe //continue; end; //prüfen ob eigene threadnummer if ( tempI = tempTHI ) then begin is_own_number := 1; // log(0,'is_own_number --> line('+ inttostr( indI ) +') = tempI : ' + inttostr( tempI ) + ' == tempTHI: ' + inttostr( tempTHI ) ); end else begin //log(0,'is_own_number -->FALSE line('+ inttostr( indI ) +') = tempI : ' + inttostr( tempI ) + ' == tempTHI: ' + inttostr( tempTHI ) ); //wenn nicht dann überspringe //continue; end; if (is_own_number = 1) then begin tempS:= ''; tempS1 := ''; tempS2:= ''; tempS3:= ''; tempS4 := ''; //kompletten pfad einlesen tempS := box.Cells[ 7, indI]; tempS1 :=''; if ( FileExists( tempS ) ) then begin byte := GetFileSize( tempS ); tempS1 := konvertBytes( byte ); delay(100); end; tempS2 :=''; tempS2 := DateTimeToStr( GetCreationTimeOfFile( tempS )); //erstellt tempS3 :=''; tempS3 := DateTimeToStr( GetFileLastAccessTime( tempS )); //letzter zugriff tempS4 :=''; tempS4 := DateTimeToStr( GetFileDate( tempS )); //geändert end; if (is_own_number = 1) then begin box.Cells[2,indI] := tempS1; //dateigrösse box.Cells[3,indI] := tempS2; //erstellt box.Cells[4,indI] := tempS3; //letzter zugriff box.Cells[5,indI] := tempS4; //geändert end; end; //thread geht komplette liste durch und bearbeitet nur seine threadnummer --> end TThread.Synchronize(nil,procedure () begin end); //task I/O ob task running (0 fetrig, 1 running, 2 soll, 3 nicht gebraucht) TaskActiveAr[ tempTHI ] := 0; log(7,'read_ALL_data->TaskActiveAr['+ inttostr(tempTHI) +'] = ' + inttostr( TaskActiveAr[tempTHI] ) + ' end'); end); Tasks[THI].Start; delay(100); //if ( THI = 11 ) then anyTaskIsRunning := 0; end; |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
gerade getestet:
begrenze ich die Threads auf 10, funktioniert alles wie es soll.. :? |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Das ist so etwas schwierig zu durchschauen.
- An welcher Stelle wird das THI erstmalig 12? Müsste man mit dem Debugger ja leicht rauskriegen können. - Pack den Code mal in Delphi-Tags (der Button mit dem Helm) statt Code-Tags - Wirf alles raus, was nicht zur Reproduktion des Fehlers nötig ist. |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Zitat:
wenn ich diesen ausklammer, funktioniert alles wieder
Delphi-Quellcode:
if ( FileExists( tempS ) ) then
begin byte := GetFileSize( tempS ); tempS1 := konvertBytes( byte ); delay(100); end; |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Ich rate mal drauf hin: es liegt an deiner eigenen Delay-Prozedur.
|
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Zitat:
Krass, stimmt. Jetzt funktionierts. Aber warum ? |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Das wissen wir erst, wenn du uns dein Delay zeigst.
|
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Zitat:
Delphi-Quellcode:
procedure Delay(const Milliseconds: DWord);
var FirstTickCount: DWord; begin FirstTickCount := GetTickCount; while ((GetTickCount - FirstTickCount) < Milliseconds) do begin Application.ProcessMessages; Sleep(0); end; end; |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Lass das ProcessMessages weg, dann sollte es funktionieren.
Oder schreibt direkt Sleep(100); in deinen Code statt Delay(100); |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Hallo,
ich kritisiere eigentlich ungern an anderer Leute Code rum, da meiner oft auch nicht besser aussieht, aber hier ist der Code wirklich ineffizient/unübersichtlich und dazu leider auch noch falsch: du versuchst ein Änderungsdatum etc. zu ermitteln, auch wenn die Datei nicht existiert(bei der Größe prüfst du vorher...) Mein Vorschlag würde wiefolgt aussehen:
Delphi-Quellcode:
for indI := 0 to box.RowCount - 1 do
begin if ( true = IsStringAInteger( box.Cells[ 9, indI] )) then begin if (strtoint(box.Cells[ 9, indI]) = tempTHI ) then begin tempS := box.Cells[ 7, indI]; if ( FileExists( tempS ) ) then begin box.Cells[2,indI] := konvertBytes( GetFileSize( tempS ) ); delay(100); box.Cells[3,indI] := DateTimeToStr( GetCreationTimeOfFile( tempS )); //erstellt box.Cells[4,indI] := DateTimeToStr( GetFileLastAccessTime( tempS )); //letzter zugriff box.Cells[5,indI] := DateTimeToStr( GetFileDate( tempS )); //geändert end; end; end; end; |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Hi und guten Morgen.
Alles gut ^^ . Ist mir auch schon aufgefallen und habe das geändert, Das baue ich mit Absicht so hin und kann dann schneller separieren. Wenn alles klappt dann sieht der Code auch so aus wie Du ihn dort geschrieben hast. - zu box.Cells[2,indI] := konvertBytes( GetFileSize( tempS ) ); leider kommt dann manchmal chinesisch raus, meine Variante beschriftet wirklich jede - weiter habe ich noch ein problem mit -- GetCreationTimeOfFile -- GetFileLastAccessTime -- GetFileDate Bei manchen Dateien werden die Daten nicht ausgelesen und der jeweilige Task bleibt dann hängen. hab gerade mal mit sleep dazwischen probiert , aber nu wird der indI 11 wieder zu 12 Task 8 ist bei dem dateinamen konten.txt hängen geblieben -> hinweis könnten Adminrechte sein ... mal schauen
Delphi-Quellcode:
if ( FileExists( tempS ) ) then
begin byte := GetFileSize( tempS ); tempS1 := inttostr( byte ); // konvertBytes( byte ); wird in seperater schleife abgefertigt //delay(100); tempS2 :=''; tempS2 := DateTimeToStr( GetCreationTimeOfFile( tempS )); //erstellt sleep(100); tempS3 :=''; tempS3 := DateTimeToStr( GetFileLastAccessTime( tempS )); //letzter zugriff sleep(100); tempS4 :=''; tempS4 := DateTimeToStr( GetFileDate( tempS )); //geändert sleep(100); end else begin tempS1 := 'n/a'; tempS2 := 'n/a'; tempS3 := 'n/a'; tempS4 := 'n/a'; end;
Delphi-Quellcode:
byte := GetFileSize( tempS );
tempS1 := inttostr( byte ); // konvertBytes( byte ); wird in seperater schleife abgefertigt Zitat:
|
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Uups, Cardinalsfehler: Ich nehme mal an, dass box ein VCL Element ist?
Wenn ja muss natürlich der Zugriff auf das box Element im Synchronize stattfinden:
Delphi-Quellcode:
aber mal eine ganz andere Frage: du willst von 12(!) Dateien die Größe, und die anderen Metadaten ermitteln. Brauchst du dafür wirklich 12 Threads? Kannst du das nicht entweder im Hauptthread oder zumindest in einem einzelnen Thread abfackel? Für mich klingt das ein wenig nach "mit Kanonen auf Spatzen schießen"
TThread.Synchronize(nil,procedure ()
begin box.Cells[2,indI] := tempS1; //dateigrösse box.Cells[3,indI] := tempS2; //erstellt box.Cells[4,indI] := tempS3; //letzter zugriff box.Cells[5,indI] := tempS4; //geändert end); |
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Liste der Anhänge anzeigen (Anzahl: 1)
Cardinalsfehler ???? erzähle mir mehr darüber...
-> mit einem ADD button wird ein Tab,2 Buttons und nen StringGrid erstellt. Dieses StringGrid = box.
Delphi-Quellcode:
//wenn array nur 1 Row dann bestehende SG nutzen ->
//ansonsten -> neues StringGrid erstellen if ( length(Sar) = 1 ) then begin n_SG := Form2.JvStringGrid1; end; if ( length(Sar) > 1 ) then begin n_SG := TJvStringGrid.Create( form2 ); n_SG.Parent := TTabSheet( Tab ); n_SG.Name := sg_navn; copy_option_JvStringGrid( form2.JvStringGrid1 , n_SG ); end; //OnDrawCell auf neue SG setzen n_SG.OnDrawCell := Form2.JvStringGrid1DrawCell;
Delphi-Quellcode:
wird später wieder zur Procedure gemacht.
function read_ALL_data( path :string; box:TJvStringGrid ):string;
aber mal eine ganz andere Frage: du willst von 12(!) Dateien die Größe,.... nee, es sollen alle Dateien mit Unterordner eingelesen werden. Also ist die Idee, die erste Struktur in eine Stringlist zu packen, dann aufzuteilen (hier / 12 oder wenn X < 12 dann = X). Sind es 24 ordner dann bekommt jeder Thread 2 Ordner die er mit Unterordner auslesen soll. Jeder Thread hat eine eigene ErgebnisStringList die nach Ablauf aller Threats zusammengeführt, sortiert und in das Stringgrid gepackt wird. Das Auslesen der Dateinamen geht wirklich deutlich schneller, jedoch mit zusätzlichen Daten (und dort bin ich gerade)ist gerade dieses futsch... Cardinalsfehler : Nu komm ich als erstes aud die IDEE die ErgebnisListe weiter zu nehmen, in nen Array zu packen, dort zu befüllen und anschliessend in die box zu übertragen? ---- So hab n Array gebastelt ---- grösse wie das StringGrid, inhalt ( kompletter dateipfad und name, indexnummer, threadaufteilung [0..11] ) also ProbeArray[ indI3, 2 ] := tempS1; //dateigrösse --> erster Versuch , tempTHI ist wieder von 10 auf 12 gesprungen. bei der Loganzeige stand (THI = 12 / tempTHI = 1) ( THI = 12 / tempTHI = 2) ( THI = 12 / tempTHI = 3 ) ... usw. hab danach das delay zwischen den tasks.start auf 600ms gesetzt. ergebnis -> jeder Thread inklusive 11 startet mit dem richtigen Integer. Ein Problem gelöst --> neues Problem Thread hängt sich bei Dateinamen wie (Image1 - Kopie.jpg) auf Zitat:
|
AW: For Schleife zählt mehr als vorhanden. iTask, for Schleife, integer -> fehler
Zitat:
![]() In TParallel.For sollten keine Synchronize Aufrufe stattfinden. Diese sind eigentlich meistens eine schlechte Idee, da sie den Thread dazu bringen zu warten. Besser ist es, das Ergebnis in eine geschützte Variable zu packen und der Oberfläche des Programmes mitzuteilen, dass sie die geschützte Variable auslesen darf um die Ergebnisanzeige zu aktualisieren. Da TParallel.For den aktuellen Prozess blockiert, muss in diesem Fall der Aufruf in einem TTask.Run() erfolgen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 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