Delphi-PRAXiS
Seite 2 von 5     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TTask.WaitForAll hängt (https://www.delphipraxis.net/201771-ttask-waitforall-haengt.html)

Luckie 24. Aug 2019 20:29

AW: TTask.WaitForAll hängt
 
Bleibt eventuell DirList hängen? Wie sieht der Code dazu aus?

Smiley 24. Aug 2019 20:58

AW: TTask.WaitForAll hängt
 
Nein, wenn ich das WaitForAll weglasse funktioniert alles problemlos.

Heuman 24. Aug 2019 21:23

AW: TTask.WaitForAll hängt
 
Hallo,
wenn ich es richtig gelesen habe wird ja auch nur ein Task gestartet.

Schokohase 24. Aug 2019 21:28

AW: TTask.WaitForAll hängt
 
Ohne den Code von
Delphi-Quellcode:
DirList
zu kennen, können wir nur mutmassen.

Es könnte sich hier um einen DeadLock handeln, der durch das Blockierende Verhalten
Delphi-Quellcode:
TTask.WaitForAll
zum Tragen kommt und es dann funktioniert wenn das Besagte eben entfernt wird.

Wird irgendwo von
Delphi-Quellcode:
DirList
ein
Delphi-Quellcode:
TThread.Synchronize
aufgerufen? Dann ist das die Ursache für den DeadLock.

Zitat:

Zitat von Heuman (Beitrag 1443016)
Hallo,
wenn ich es richtig gelesen habe wird ja auch nur ein Task gestartet.

Ja, und jetzt?

Heuman 24. Aug 2019 21:59

AW: TTask.WaitForAll hängt
 
[QUOTE=Schokohase;1443023]Ohne den Code von
Delphi-Quellcode:
DirList
zu kennen, können wir nur mutmassen.

wie geschrieben, falsch gelesen.

Gruß

Schokohase 24. Aug 2019 22:09

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von Heuman (Beitrag 1443024)
wie geschrieben, falsch gelesen.

Eeh, nein
Zitat:

Zitat von Heuman (Beitrag 1443016)
Hallo,
wenn ich es richtig gelesen habe wird ja auch nur ein Task gestartet.

Es wird nur ein Task gestartet.

Du hast also richtig gelesen. Aber wo soll da das Problem sein?

p80286 24. Aug 2019 22:27

AW: TTask.WaitForAll hängt
 
Zitat:

Zitat von Smiley (Beitrag 1443014)
Nein, wenn ich das WaitForAll weglasse funktioniert alles problemlos.

Na dann ist doch gut!

Oder meinst Du, daß die Oberfläche nicht einfriert und irgendwann die gewünschten Daten zur Verfügung stehen?

Da ich TTask nicht kenne kann ich nur beschreiben wie ich das mit TTHread gelöst hätte.
Da wird als letzte Aktion vor dem selbstmord des Threads eine "Endmessage" gesandt. dann weiß das Programm, daß ein Thread beendet wurde und gut ist.

Gruß
K-H

Smiley 24. Aug 2019 22:33

AW: TTask.WaitForAll hängt
 
Hier die DirList Routine.
Wenn nur ein Task läuft, wo soll dann ein Deadlock eintreten ???
Das WaitForAll wird in dem Beispiel von Embarcadero verwendet und ich wollte es benutzen um nicht mit einem eigene Flag arbeiten zu müssen.

Kann ich dann mal ein Beispiel mit EndMessage sehen ?

Delphi-Quellcode:
// *****************************************************************************
procedure TForm1.DirList;
var
  // SearchResult
  MainVerz: TStringDynArray;
  SearchResult: TStringDynArray;
  FilterMaske: String;

  I: Integer;
begin

  StartFolder := '\\SCHLUPP\Praktikant\Delphi\Tutorial\';

  // Filter für *.pdf, *.docx,...
  FilterMaske := '*.*';

  // Grid.StartUpdate;
  GridInit;
  AktLine := 1;
  ListBox1.clear;

  // Uses IOUtils für GetDir..und System.Types für DynArray hinzufügen
  // Alle Hauptverzeichnisse einlesen und dann pro Verz. eine Suche ausführen in eigenem Thrad
  StartTime := Now();
  MainVerz := TDirectory.GetDirectories(StartFolder, TSearchOption.soTopDirectoryOnly, nil);
  Form1.ProgressBar1.Max := high(MainVerz);
  qV.Open;
  for j := 0 to High(MainVerz) do
    begin
      ListBox1.Items.Add(MainVerz[j]);
      try
        Begin
          // Einlesen der Dateien ab dem Verz[j]
          SearchResult := TDirectory.GetFiles(MainVerz[j], FilterMaske, TSearchOption.soAllDirectories);
          for I := 0 to High(SearchResult) do
            begin
              if SearchResult[I] <> '' then
                begin
                  // grid.Cells[1, AktLine] := ExtractFilename(SearchResult[I]);
                  // grid.Cells[2, AktLine] := ExtractFilePath(SearchResult[I]);
                  qV.append;
                  qV.FieldByName('Verzeichnis').AsString := ExtractFilePath(SearchResult[I]);
                  qV.FieldByName('Datei').AsString := ExtractFileName(SearchResult[I]);
                  qV.FieldByName('Kategorie').AsString := '';
                  qV.Post;
                  inc(AktLine);
                end;
            end;
          ListBox1.Items.Add('Task ' + IntToStr(j) + ' Zeit: ' + FormatDateTime('hh:nn:ss:zzz', Now - StartTime));
          StartTime := Now();
          ListBox1.Refresh;
        End;
      except
        // Catch the possible exceptions
        MessageDlg('Incorrect path or search mask', mtError, [mbOK], 0);
        Exit;
      end;
      Form1.ProgressBar1.Position := j;
    end;
  LTaskRun := false;
end;

Schokohase 24. Aug 2019 23:06

AW: TTask.WaitForAll hängt
 
Ein Task, der in einem Thread läuft und der MainThread sind bei mir zwei Threads.

Aber du weißt das anscheinend besser und da kann ich natürlich nicht helfen. Entschuldige die Störung.

haentschman 25. Aug 2019 05:55

AW: TTask.WaitForAll hängt
 
Moin...8-)
Zitat:

Ein Task, der in einem Thread läuft und der MainThread sind bei mir zwei Threads.
...er hat Recht. :zwinker:
Zitat:

Wird irgendwo von DirList ein TThread.Synchronize aufgerufen? Nein? Dann ist das die Ursache für den DeadLock.
...das Nein hat gefehlt. :zwinker:
Delphi-Quellcode:
  for j := 0 to High(MainVerz) do
    begin
      ListBox1.Items.Add(MainVerz[j]);
      // ListBox: niemals aus einem Thread auf das Control zugreifen. Nur mit Synchronize über ein Event!
      try
        Begin
          // Einlesen der Dateien ab dem Verz[j]
          SearchResult := TDirectory.GetFiles(MainVerz[j], FilterMaske, TSearchOption.soAllDirectories);
          for I := 0 to High(SearchResult) do
            begin
              if SearchResult[I] <> '' then
                begin
                  // grid.Cells[1, AktLine] := ExtractFilename(SearchResult[I]);
                  // grid.Cells[2, AktLine] := ExtractFilePath(SearchResult[I]);
                  qV.append;
                  qV.FieldByName('Verzeichnis').AsString := ExtractFilePath(SearchResult[I]);
                  qV.FieldByName('Datei').AsString := ExtractFileName(SearchResult[I]);
                  qV.FieldByName('Kategorie').AsString := '';
                  qV.Post;
                  inc(AktLine);
                end;
            end;
          ListBox1.Items.Add('Task ' + IntToStr(j) + ' Zeit: ' + FormatDateTime('hh:nn:ss:zzz', Now - StartTime)); /
          // ListBox: niemals aus einem Thread auf das Control zugreifen. Nur mit Synchronize über ein Event!
          StartTime := Now();
          ListBox1.Refresh;
        End;
      except
        // Catch the possible exceptions
        MessageDlg('Incorrect path or search mask', mtError, [mbOK], 0);
        Exit;
      end;
      Form1.ProgressBar1.Position := j;
      // Form: niemals aus einem Thread auf die Form zugreifen. Nur mit Synchronize über ein Event!
    end;
  LTaskRun := false;
end;
Jetzt rächt sich wieder einmal RAD. Jede procedure kennt alle Units / Controls. :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:00 Uhr.
Seite 2 von 5     12 34     Letzte »    

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