AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

Ein Thema von KodeZwerg · begonnen am 13. Nov 2018 · letzter Beitrag vom 14. Nov 2018
Antwort Antwort
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.629 Beiträge
 
Delphi 12 Athens
 
#1

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 13. Nov 2018, 23:49
Jo nichts anderes als PostMessage im weitläufigen sinne.
Nur das Queue eben nicht mit PostMessage arbeitet (muss ja auch für die anderen Plattformen gehen). Wenn man das Szenario mal theoretisch mit der Windows Message Queue umsetzen wollte, dann würde der Thread beim Beenden noch schnell alle PostMessage Calls, die er gemacht hat und die noch in der Message Queue drin stecken einfach da rauslöschen.

@Alle: Es würde mich prinzipiell mal interessieren, ob mein Beispiel auch auf anderen Systemen das Problem verlässlich nachbildet.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 14. Nov 2018, 03:07
So macht es mehr oder weniger was ich wollte, nun werden nach und nach die icons geladen und dargestellt unabhängig vom mainthread.

Delphi-Quellcode:
procedure TfrmMain.StartIcons3();
begin
  TThread.CreateAnonymousThread(procedure ()
    var
      LIcon: TIcon;
      dummy: Word;
      I: Integer;
    begin
      FileIcons.BeginUpdate;
      LIcon := TIcon.Create;
      LIcon.Transparent := True;
      lvFiles.Column[0].MinWidth := 37;
      lvFiles.Column[0].MaxWidth := 37;
      lvFiles.Column[0].Width := 37;
      lvFiles.SmallImages := FileIcons;
      try
        for i := 0 to lvFiles.Items.Count -1 do
          begin
            dummy := 0;
            TThread.Synchronize (TThread.CurrentThread,
              procedure ()
                begin
                  LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( lvFiles.Items.Item[ i ].Caption ), dummy );
                end);
            LIcon.Transparent := True;
            dummy := FileIcons.AddIcon( LIcon );
            DestroyIcon( LIcon.Handle );
            TThread.Synchronize (TThread.CurrentThread,
              procedure ()
                begin
                  lvFiles.Items.Item[ i ].ImageIndex := dummy;
                end);
          end;
      finally
        TThread.Synchronize (TThread.CurrentThread,
          procedure ()
            begin
              FileIcons.EndUpdate;
            end);
        LIcon.Free;
      end;
    end).Start;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
678 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 14. Nov 2018, 08:30
Ich finde es gerade nirgendwo dokumentiert, aber so wie die VCL nicht thread-safe ist, würde ich nie Windows-Handles zwischen Threads austauschen. Das knallt im Zweifel irgendwann irgendwo ohne dass man den Kontext erkennt.
Den Icon-Stream zwischen den Threads auszutauschen hat zudem den Vorteil, dass Duplikate einfach vermieden werden können. Und ein Icon-Cache macht gerade bei Netzwerklaufwerken enorm sein.
Spätestens dann machen anonyme Methoden/Threads immer weniger Sinn und schaden massiv der Übersichtlichkeit.

Ich würde das so umsetzen (da fehlt noch ein wenig Fehlerbehandlung, und verbessern kann man natürlich immer):
https://github.com/CCRDude/tlistview-icon-cache-demo
Ist LCL, aber VCL dürfte identisch sein, lediglich die Generics müssten angepasst werden, da nutze ich FreePascal sonst immer im objpas-Modus und bin mir nicht sicher, wie die entsprechenden Delphi-Klassen heißen.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.073 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)

  Alt 14. Nov 2018, 07:58
@Alle: Es würde mich prinzipiell mal interessieren, ob mein Beispiel auch auf anderen Systemen das Problem verlässlich nachbildet.
Ja, es zeigt es ganz gut (Win 10, 10.2.3).
Mit der Verwendung von procedure TThread.Queue(AThreadProc: TThreadProcedure); wird beim Zerstören des Threads alle Warteschlangen-Ereignisse entfernt - da dann hier Self verwendet wird - und man kommt nie bis zur Zahl 100 im Memo.
Oft kommt auch gar nichts an (das hat mich dann doch überrascht).

Wenn man es umschreibt und class procedure TThread.Queue(const AThread: TThread; AMethod: TThreadMethod); mit nil als ersten Parameter verwendet, dann arbeitet der Hauptthread noch alles ab.
Hier geht das natürlich und ist unkritisch, aber wehe, man hat richtigen Code und greift auf Ressourcen des Threads zu.
Vielen Dank, wieder was gelernt.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:15 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