Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund (https://www.delphipraxis.net/204073-ttask-run-problem-der-task-laeuft-nicht-fluessig-im-hintergrund.html)

Chemiker 21. Apr 2020 10:37

Delphi-Version: 10.3 Rio

TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund
 
Hallo zusammen,

in dem Beispiel-Code wird aus Excel Daten in eine Generics TObjectList<T> eingelesen. Das funktioniert auch so wie soll, allerdings lasse ich einen ActivityIndicator mitlaufen der aber nicht flüssig durchläuft mal komplett stehen bleibt usw.. Die Frage ist jetzt warum ist das so und wie kann man das Ändern?

Delphi-Quellcode:
TTask.Run(
      Procedure
      var
        i: integer;
      begin
        begin
          TThread.Queue(NIL,
          Procedure
          begin
            Memo1.Lines.add('Thread-Beginn ' + TimeToStr(Now));
          end);
       try
          for i := 0 to ExcelZeilen -1 do
          begin
            TThread.Synchronize (NIL,
              Procedure
              begin
                frmArtikelListe.gArt_Liste.Add(i +1,
                  EXCEL.ZellenInhalt(i + 1,1), EXCEL.ZellenInhalt(i + 1, 2));
              end);
          end;
        except
          TThread.Queue(NIL,
            Procedure
            begin
              Memo1.Lines.add('Fehler ' + TimeToStr(Now));
            end);
        end;
        TThread.Queue(NIL,
          Procedure
          begin
            Memo1.Lines.add('Thread-Ende ' + TimeToStr(Now));
            EXCEL.free;
            ActivityIndicator1.Animate := FALSE;
            GridAusgabe;
          end);
        end;
      end);
Bis bald Chemiker

Sherlock 21. Apr 2020 11:02

AW: TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund
 
Die "Flüssigkeit" des ActivityIndicator hängt ja eher davon ab, wie gerade das System ausgelastet ist, was die MainForm sonst so treibt, wie anspruchsvoll die Berechnung gerade war...etc. So 100% flüssig dürfte das mMn nie werden.

Sherlock

Der schöne Günther 21. Apr 2020 11:47

AW: TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund
 
Stehe ich auf dem Schlauch oder macht dein Task irgendetwas?

Du schiebst alles in den Hauptthread. Alles. Der Task ist vollkommen überflüssig.

himitsu 21. Apr 2020 11:53

AW: TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund
 
Da im Grunde der komplette Thread/Task sinnlos ist, weil praktisch ALLES im Haupthtread abläuft,
ist der Haupthead somit voll ausgelastet.

Entweder es ist möglich EXCEL und gArt_Liste im Thread zu nutzen,
oder die unzähligen Synchronisierungen fressen nur unnötig viel Zeit/Ressourcen.


Das Einzige, wozu es sowas gut ist: Es verschwendet sinnlos mehr Rechenleistung, um anderen Threads zwischendrin bissl Rechenzeit abzugeben,
und das kann man auch selber machen.



Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
var
  i: integer;
begin
  Memo1.Lines.add('Thread-Beginn ' + TimeToStr(Now));
  try
    for i := 0 to ExcelZeilen -1 do
    begin
      frmArtikelListe.gArt_Liste.Add(i +1,
        EXCEL.ZellenInhalt(i + 1,1), EXCEL.ZellenInhalt(i + 1, 2));
      if i mod 100 = 0 then
        Application.ProcessMessages;
    end;
  except
    Memo1.Lines.add('Fehler ' + TimeToStr(Now));
  end;
  Memo1.Lines.add('Thread-Ende ' + TimeToStr(Now));
  EXCEL.Free;
  ActivityIndicator1.Animate := FALSE;
  GridAusgabe;
end;
Wobei ich ungern unberechenbare "Abtände" haben möchte und daher lieber mit berechenbaren Zeiten arbeite.
Delphi-Quellcode:
    C := GetTickCount;
    for i := 0 to ExcelZeilen -1 do
    begin
      frmArtikelListe.gArt_Liste.Add(i +1,
        EXCEL.ZellenInhalt(i + 1,1), EXCEL.ZellenInhalt(i + 1, 2));
      if (GetTickCount - C) > 100 then begin // siehe unten
        Application.ProcessMessages;
        C := GetTickCount;
      end;
    end;
z.B. mal mit 50, 100, 250 oder 500 Millisekunden ausprobieren, wobei 100 bis 250 oft gut aussehen.


Persönlich würde ich auch empfehlen OnCreate/Constructor nicht unnötig lange laufen zu lassen.
Wie wäre es mit OnShow?

Rollo62 21. Apr 2020 14:41

AW: TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund
 
Ich würde versuchen die Teile im Thread erstmal partiell in einen Zwischenspeicher zu laden,
und dann in Chunk's, z.B. alle 100 Zeilen, in den MainThread nach gArt_Liste kopieren.

So hat der Thread zumindest etwas zu tun, vorrausgesetzt das Excel.Laden ist kostenintensiver als das Übertragen in die gArt_Liste der Form.

Chemiker 21. Apr 2020 16:53

AW: TTask.Run Problem, der Task läuft nicht flüssig im Hintergrund
 
Hallo,

danke für die Antworten.

Ich habe mich wohl komplett in die falsche Richtung bewegt, himitsu das ist mehr oder weniger der Ausgangscode von 2006. Es werden zwar Ressourcen verschwendet, das ist aber bei 30000 Artikel nur ca. 1 sek..
Ich werde über das Problem nochmal neu nachdenken müssen.

Bis bald Chemiker


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz