Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Kann ich meine ListView beschleunigen (Icon laden dauert ewig) (https://www.delphipraxis.net/198553-kann-ich-meine-listview-beschleunigen-icon-laden-dauert-ewig.html)

KodeZwerg 13. Nov 2018 11:16

Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
So sieht meine füll routine aus:
Delphi-Quellcode:
in .dfm
  object FileIcons: TImageList
    BlendColor = clGradientInactiveCaption
    BkColor = 15918295
    Masked = False
    Left = 632
    Top = 32
  end

...
    FileIcons: TImageList;
...

procedure DoIt();
var
  i: Integer;
  SL2: TStringDynArray;
  SL2idx: Integer;
  Icon: TIcon;
  dummy: Word;
begin
  dummy := 0;
  SL2idx := 0;
  SetLength( SL2, 1 );

...code um SL zu füllen...

  if SL2idx > 0 then   Dec( SL2idx );
  SetLength( SL2, SL2idx );
  Icon := TIcon.Create;
  Icon.Transparent := True;
  lvFiles.Items.BeginUpdate;
  for i := 0 to Length( SL2 ) -1 do
    with lvFiles.Items.Add() do
      begin
        if cbUseIcons.Checked then
          Icon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( SL2[ i ] ), dummy );
        Icon.Transparent := True;
        ImageIndex := FileIcons.AddIcon( Icon );
        DestroyIcon( Icon.Handle );
        Caption := SL2[ i ];
    end;
  lvFiles.Items.EndUpdate;
  Icon.Free;
end;
Lasse ich das Icon laden weg = hab ich fast sofort die Ergebnisse dargestellt
Nehm ich Icon mit rein dauert es teilweise ewig.

Mach ich da was falsch?

DieDolly 13. Nov 2018 11:21

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Lädst du mit ExtractAssociatedIcon ein Icon einer Datei? Wenn ja liegt es an diesen IO-Zugriffen. SHGetFileInfo ist eventuell schneller.
Besser ist es aber die Icons schon vorher in eine ImageList zu laden und dann direkt von der ImageList ins ListView zu transportieren.

Delphi.Narium 13. Nov 2018 11:33

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Daten- / Iconmenge?

Programm beim Laden der Icons minimieren, damit nicht dauernd "neu gemalt" wird.

irgendwie sowas:
Delphi-Quellcode:
  Application.Minimize;
  lvFiles.Items.BeginUpdate;
...
  lvFiles.Items.EndUpdate;
  Application.Restore;
Die Bildschirmausgabe ist nachwievor das Langsamste bei Programmen ;-)

DieDolly 13. Nov 2018 11:37

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

Programm beim Laden der Icons minimieren, damit nicht dauernd "neu gemalt" wird.
Reicht dafür nicht Begin und EndUpdate für das ListView?

KodeZwerg 13. Nov 2018 11:41

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
SHGetFileInfo hatte ich vorher, liefert aber nicht immer das zurück was ich möchte. Zwischen den beiden ist kein Nennenswerter Geschwindigkeits-Unterschied.

Ja die IO Zugriffe sind da enorm beansprucht, da falls kein Icon in Datei sein sollte sucht Windows nach dem nächst besten (also mit ExtractAssociatedIcon, die SH-Variante gibt da zu schnell auf und liefert blanko-Template wieder, was nicht unbedingt ein schnelleres Ergebnis bedeutet)

Was ich allerdings im Hinterkopf habe, wenn ich ListView mit ShellListView-Demo vergleiche, bei der Shell-Variante ist ein kompletter Dateipfad schwupps die wupps geladen, sogut wie Verzögerungsfrei. Selbst bei Ordnern mit mehreren Tausend Dateien.

Vielleicht kann ich das ja irgendwie für mich Nutzbar machen, am Ende bleibt es ja eine ListView.

Danke für die Idee es vorher in die ImageList zu laden und beim ListView.Add() nurnoch index dahin setzen, werde ich auf jeden Fall mal ausprobieren, ob es schneller geht, wer weiß :)

Uwe Raabe 13. Nov 2018 11:43

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Probier mal ein
Delphi-Quellcode:
FileIcons.BeginUpdate/EndUpdate
um den Ladevorgang zu legen.

KodeZwerg 13. Nov 2018 11:48

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

Zitat von Delphi.Narium (Beitrag 1417938)
Die Bildschirmausgabe ist nachwievor das Langsamste bei Programmen ;-)

Okay, kann ich probieren, vorm .EndUpdate mal minimieren danach wiederherstellen. Ist ein Versuch Wert!

Zitat:

Zitat von Uwe Raabe (Beitrag 1417941)
Probier mal ein
Delphi-Quellcode:
FileIcons.BeginUpdate/EndUpdate
um den Ladevorgang zu legen.

Boah, wusste noch garnicht das es sowas gibt, das teste ich auch!


Ich melde mich nach Tests wieder.

Dateimenge sind mal 50 mal 500, selten mehr. Aber selbst bei 20-30 Dateien dauert es manchmal 20-30 sekunden. Trotz SSD.

KodeZwerg 13. Nov 2018 11:59

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Bin mit guten Nachrichten zurück, also das FileIcons.Begin/EndUpdate brachte schonmal etwas boost, rein objektiv Betrachtet.
Delphi-Quellcode:
  Application.Minimize;
  lvFiles.Items.EndUpdate;
  FileIcons.EndUpdate;
  Application.Restore;
  Application.BringToFront;
aber das wirkt tatsächlich Wunder, kann ich nur Weiterempfehlen! Besten Dank für Tipps, hab ich aufgesaugt und werde es mir merken!

Ich teste jetzt noch ob das füllen der Icons seperat vom ListView.Add() was bringt.


Beste Grüße!

CCRDude 13. Nov 2018 12:12

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

Ob ein Thread hier hilft, bin ich mir nicht sicher, da es ja um Icon-Handles geht, die im Haupthread stehen müssen.
Aber mindestens die Liste laden und erst danach im OnIdle die Icons stückweise nachladen könnte eine Option sein?

Oder nur die Icons der in der Liste aktuell sichtbaren Einträge laden und die anderen beim Scrollen nachladen?

Ggfls auch Icons cachen, macht die Shell ja auch.

KodeZwerg 13. Nov 2018 12:23

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
@CCRDude, die Idee gefällt mir, sehr sogar!
Also Icon routine komplett aus meiner Füll methode raus, wenn die fertig ist einen Thread starten der dann poe á poe Icons cached und in ListView das Index dafür setzt.
Hab ich ehrlich gesagt noch nie probiert, cooler Gedanke, das werde ich mal separat testen.

Ob mein MainThread momentan hängt kann mir ziemlich egal sein denn ohne ListView kann das Teil nichts :-]

Hobbycoder 13. Nov 2018 13:03

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Hm...würde mir einer mal erklären, warum BeginUpdate und EndUpdate einer ListView nicht ausreichen, und zusätzlich noch das Minimize btw. Restore mehr Geschwindigkeit bringen soll?

DieDolly 13. Nov 2018 13:09

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

wenn die fertig ist einen Thread starten der dann poe á poe Icons cached und in ListView das Index dafür setzt.
Warum so kompliziert und nicht einfach die Icons in eine ImageList stecken. Meinet wegen sogar in einem Thread. Aber das ge-cache bringt mal gar nix verglichen zu einer ImageList.
Zitat:

und zusätzlich noch das Minimize btw. Restore mehr Geschwindigkeit bringen soll?
Ich stelle mir gerade ein Programm vor, das sich einfach während der Nutzung mal minimiert und wieder maximiert. Sähe sehr vertrauenswürdig aus :D

Delphi.Narium 13. Nov 2018 13:28

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

Zitat von Hobbycoder (Beitrag 1417947)
Hm...würde mir einer mal erklären, warum BeginUpdate und EndUpdate einer ListView nicht ausreichen, und zusätzlich noch das Minimize btw. Restore mehr Geschwindigkeit bringen soll?

Weil dann jegliche Aktuallisierung des Bildschirmes / der Anzeige wegfällt. Und das dauert unter Windows halt.

Ist 'ne langjährige praktische Erfahrung / Beobachtung, die man halt ausnützen kann, wenn was schneller gehen soll.

Und ja @DieDolly, anwenderfreundlich ist was anderes ;-)

KodeZwerg 13. Nov 2018 13:46

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Delphi-Quellcode:
procedure TfrmMain.StartIcons();
begin
  TThread.CreateAnonymousThread(procedure ()
    var
      LIcon: TIcon;
      I: Integer;
      dummy: Word;
    begin
      dummy := 0;
      LIcon := TIcon.Create;
      LIcon.Transparent := True;
      try
        lvFiles.Update;
        FileIcons.BeginUpdate;
        for i := 0 to lvFiles.Items.Count -1 do
          begin
            LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( lvFiles.Items.Item[ i ].Caption ), dummy );
            LIcon.Transparent := True;
            lvFiles.Items.Item[ i ].ImageIndex := FileIcons.AddIcon( LIcon );
            DestroyIcon( LIcon.Handle );
          end;
        TThread.Synchronize (TThread.CurrentThread, procedure ()
          begin
          end);
      finally
        FileIcons.EndUpdate;
        LIcon.Free;
      end;
    end).Start;
end;
Ich habe die Idee mit Thread mal auf diese Weise ausprobiert, also Geschwindigkeit boost ohne ende, aber irgendwas mach ich da noch falsch, jetzt werden viele Icons nicht korrekt geladen.

DeddyH 13. Nov 2018 13:50

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Niemals unsynchronisiert aus einem Thread heraus auf VCL-Controls zugreifen, das ist eine uralte Weisheit.

EWeiss 13. Nov 2018 13:55

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

TThread.Synchronize (TThread.CurrentThread, procedure ()
begin
end);
Nun ja man muss da schon etwas zwischen pappen und zwar die Funktion die vom Mainthread verwendet wird um die Icons zu Zeichen.
Im Moment macht Synchronize gar nichts.

Und dann kannst du auch nicht sicher sein ob Synchronize das richtige ist denke mal nicht denn du möchtest ja nicht warten oder?
Denn dann dauert es wieder genauso lang.
Spiele mal mit Queue und Synchronize rum dann nimm das was am besten für dich ist.

gruss

Daniel 13. Nov 2018 13:56

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Wo kommt denn der Geschwindigkeitsvorteil her?
Vorher wurde alles im Mainthread gemacht, jetzt alles in einem einzigen Thread. Die Arbeit wurde 1:1 verlagert. Einen Vorteil hast Du doch erst, wenn Du mehrere Threads auf das Problem loslässt und somit mehrere Kerne nutzt. :gruebel:

KodeZwerg 13. Nov 2018 13:56

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

Zitat von DeddyH (Beitrag 1417953)
Niemals unsynchronisiert aus einem Thread heraus auf VCL-Controls zugreifen, das ist eine uralte Weisheit.

Delphi-Quellcode:
procedure TfrmMain.StartIcons();
begin
  TThread.CreateAnonymousThread(procedure ()
    var
      LIcon: TIcon;
      I: Integer;
      dummy: Word;
    begin
      dummy := 0;
      LIcon := TIcon.Create;
      LIcon.Transparent := True;
      try
        lvFiles.Update;
        FileIcons.BeginUpdate;
        for i := 0 to lvFiles.Items.Count -1 do
        begin
          begin
            LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( lvFiles.Items.Item[ i ].Caption ), dummy );
            LIcon.Transparent := True;
          end;
        TThread.Synchronize (TThread.CurrentThread, procedure ()
          begin
            lvFiles.Items.Item[ i ].ImageIndex := FileIcons.AddIcon( LIcon );
          end);
        DestroyIcon( LIcon.Handle );
        end;
      finally
        FileIcons.EndUpdate;
        LIcon.Free;
      end;
    end).Start;
end;
Danke, ich habe es auf diese Weise korrigiert aber das Problem besteht immer noch, ich finde meinen Fehler nicht.

Delphi.Narium 13. Nov 2018 14:00

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
DeddyHs Hinweis auf alle VCL-Controls anwenden und nicht nur auf eine Zeile? ;-)

EWeiss 13. Nov 2018 14:01

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

Danke, ich habe es auf diese Weise korrigiert aber das Problem besteht immer noch, ich finde meinen Fehler nicht.
Lies noch mal meinen Beitrag..
Du verwendest SendMessage besser wäre PostMessage wenn du nicht warten willst.

Zitat:

DeddyHs Hinweis auf alle VCL-Controls anwenden und nicht nur auf eine Zeile?
Richtig der ganze kram mit dem Icon erstellen usw.. muss da rein.
Du kannst TThread wie eine normale procedure behandeln falls du das nicht weist.

Delphi-Quellcode:
TThread.Synchronize (TThread.CurrentThread,
procedure ()
var
// Meine Variablen
begin
// Meine Funktion
end);
gruss

KodeZwerg 13. Nov 2018 14:03

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Ich hoffe *bet* das ichs jetzt gerafft habe:
Delphi-Quellcode:
procedure TfrmMain.StartIcons();
begin
  TThread.CreateAnonymousThread(procedure ()
    var
      LIcon: TIcon;
      dummy: Word;
    begin
      dummy := 0;
      LIcon := TIcon.Create;
      LIcon.Transparent := True;
      try
        TThread.Synchronize (TThread.CurrentThread, procedure ()
          var
            I: Integer;
          begin
            lvFiles.Update;
            FileIcons.BeginUpdate;
            for i := 0 to lvFiles.Items.Count -1 do
              begin
                LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( lvFiles.Items.Item[ i ].Caption ), dummy );
                LIcon.Transparent := True;
                lvFiles.Items.Item[ i ].ImageIndex := FileIcons.AddIcon( LIcon );
                DestroyIcon( LIcon.Handle );
              end;
          end);
      finally
        FileIcons.EndUpdate;
        LIcon.Free;
      end;
    end).Start;
end;

EWeiss 13. Nov 2018 14:11

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Delphi-Quellcode:
TThread.Synchronize (TThread.CurrentThread,


Bist sicher? Nicht Nil!
Nur mal als sample

Delphi-Quellcode:
function TSessionThread.OnSessionCreated(NewSession: IAudioSessionControl): HResult;
begin

  Result := S_FALSE;

  if (MainThreadID <> GetCurrentThreadId) then
  begin
    TThread.Queue(nil,
      procedure
      var
        bDuplicate: BOOL;
        i: Integer;
      begin
        if Assigned(FOnAudioSessionCreate) then
        begin
          ASessionInfo := GetSessionInfo(NewSession);
          if ASessionInfo.FileName <> '' then
          begin
            // Check to prevent duplicate registeration of audio session
            bDuplicate := false;
            for i := 0 to (FSessionCount - 1) do
           if SessionInfo[i].PID = ASessionInfo.PID then
           begin
             // for the case of reuse of same PID (but different programs)
             if SessionInfo[i].State <> AudioSessionStateExpired then
             begin
               bDuplicate := true;
               Break;
             end;
          end;

          if not bDuplicate then
          begin
            inc(FSessionCount);
            SetLength(SessionInfo, FSessionCount);
            SessionInfo[FSessionCount - 1] := ASessionInfo;
            FOnAudioSessionCreate(NewSession, ASessionInfo, FSessionCount);
          end;
        end;
      end;
    end);
    Result := S_OK;
  end;
end;
Zitat:

Warum so kompliziert und nicht einfach die Icons in eine ImageList stecken.
Und du kennst alle Icons von Programmen die er auslesen will auch unbekannte die noch niemals auf seiner Platte waren also im Moment unbekannt sind?
Super na ja dann addiere die unbekannten mal zur Imagelist. ;)
Ist doch einfach oder? :)

gruss

KodeZwerg 13. Nov 2018 14:36

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Mein nächster Versuch, bis jetzt mehr als gescheitert, bin noch auf Fehlersuche.

Hab mal im Soure kommentiert so wie ich es dachte das es funktioniert:
Delphi-Quellcode:
//dieses mal mit eingabe
procedure TfrmMain.StartIcons( ListView: TListView; ImageList: TImageList );
begin
  // hier soll ein Thread abseits des Mainthreads starten um diesen zu entlasten
  TThread.CreateAnonymousThread(procedure ()
    var // <- locale variablen für den Thread
      LIcon: TIcon;
      dummy: Word;
      I: Integer;
      LImageList: TImageList;
      LListView: TListView;
    begin
      dummy := 0;
      LListView := TListView.Create( nil );
      LImageList := TImageList.Create( nil );
      LIcon := TIcon.Create();
      LIcon.Transparent := True;
      LImageList.BeginUpdate;
      LImageList.Assign( ImageList ); // <-- lokale kopie der aktuellen liste
      LListView.Items.BeginUpdate;
      LListView.Assign( ListView ); // <-- lokale kopie der aktuellen liste
      try // <-- beginne mit der arbeit an den lokalen kopien
        for i := 0 to LListView.Items.Count -1 do
          begin
            LIcon.Handle := ExtractAssociatedIcon( hInstance, PWideChar( LListView.Items.Item[ i ].Caption ), dummy );
            LIcon.Transparent := True;
            LListView.Items.Item[ i ].ImageIndex := LImageList.AddIcon( LIcon );
            DestroyIcon( LIcon.Handle );
          end;
        LImageList.EndUpdate;
        LListView.Items.EndUpdate;
        TThread.Synchronize (nil, procedure () // übergebe lokale kopien zurück an vcl
          begin
            FileIcons.BeginUpdate;
            FileIcons.Assign( LImageList );
            FileIcons.EndUpdate;
            lvFiles.Items.BeginUpdate;
            lvFiles.Assign( LListView );
            lvFiles.Items.EndUpdate;
          end);
      finally
        LIcon.Free;
        LImageList.Free;
        LListView.Free;
      end;
    end).Start;
end;
das ist momentan die schnellste variante, da sie nicht funktioniert :-]

dummzeuch 13. Nov 2018 14:38

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

Zitat von Delphi.Narium (Beitrag 1417950)
Zitat:

Zitat von Hobbycoder (Beitrag 1417947)
Hm...würde mir einer mal erklären, warum BeginUpdate und EndUpdate einer ListView nicht ausreichen, und zusätzlich noch das Minimize btw. Restore mehr Geschwindigkeit bringen soll?

Weil dann jegliche Aktuallisierung des Bildschirmes / der Anzeige wegfällt. Und das dauert unter Windows halt.

Statt minimieren ginge vermutlich auch WM_SETREDRAW.

EWeiss 13. Nov 2018 14:58

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
OK letzter Tip.. Doublebuffer true?

gruss

Sherlock 13. Nov 2018 15:02

AW: Kann ich meine ListView beschleunigen (Icon laden dauert ewig)
 
Eigentlich bietet sich TParallel.For hierfür an.

Sherlock

DieDolly 13. Nov 2018 15:02

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

Und du kennst alle Icons von Programmen die er auslesen will auch unbekannte die noch niemals auf seiner Platte waren also im Moment unbekannt sind?
Super na ja dann addiere die unbekannten mal zur Imagelist.
Ist doch einfach oder?
Die wenigen unbekannten die es wohl sein werden, kann man locker am Ende hinzufügen. Der Geschwindigkeitsvorteil, wenn man man alle Icons anfangs in eine Liste lädt, sind enorm.

Zitat:

Und du kennst alle Icons von Programmen die er auslesen will
Er ließt sie ja so oder so in einer Schleife aus. Also sind sie nicht unbekannt.


Zitat:

Zitat von Daniel (Beitrag 1417955)
Wo kommt denn der Geschwindigkeitsvorteil her?
Vorher wurde alles im Mainthread gemacht, jetzt alles in einem einzigen Thread. Die Arbeit wurde 1:1 verlagert. Einen Vorteil hast Du doch erst, wenn Du mehrere Threads auf das Problem loslässt und somit mehrere Kerne nutzt. :gruebel:

Wie Sherlock sagt: TParallel.For. Das in einen Thread und anschließend aus einer ImageList lesen. Schon hat man einen guten Geschwindigkeitsvorteil.

Daniel 13. Nov 2018 15:10

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

Zitat von DieDolly (Beitrag 1417975)
Wie Sherlock sagt: TParallel.For. Das in einen Thread und anschließend aus einer ImageList lesen. Schon hat man einen guten Geschwindigkeitsvorteil.

Bin ich bei Dir, dass das mit
Delphi-Quellcode:
TParallel.For
geht. Das Code-Beispiel, auf das ich mich bezog, enthält das jedoch genau nicht - wurde aber mit "Geschwindigkeit boost ohne ende" klassifiziert.

DieDolly 13. Nov 2018 15:11

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

wurde aber mit "Geschwindigkeit boost ohne ende" klassifiziert.
TParallel.For habe ich schon oft in Threads verwendet. Den krassesten Boost bekommt man, wenn man genau dann eben keine IO-Befehle ausführen muss und die schon vorher erledigt hat.
Wenn man im TParallel.For noch auf die Festplatte zugreifen muss, dann braucht man auch keine TParallel mehr nutzen denn dann schadet das eher.

KodeZwerg 13. Nov 2018 15:27

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

Zitat von Daniel (Beitrag 1417978)
Das Code-Beispiel, auf das ich mich bezog, enthält das jedoch genau nicht - wurde aber mit "Geschwindigkeit boost ohne ende" klassifiziert.

Ich hatte da wirklich einen mega boost, weil alle Dateien die nicht .ico oder als resource ein mainicon haben einfach übersprungen werden und als retoure bekommt man ein blanko icon.

Schokohase 13. Nov 2018 15:53

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

Zitat von EWeiss (Beitrag 1417962)
Delphi-Quellcode:
TThread.Synchronize (TThread.CurrentThread,
Bist sicher? Nicht Nil!

Du kannst da übergeben was du möchtest - der Wert wird im Prinzip nicht wirklich verwendet.

Die Thread-Instanz wird in einen Record geschrieben:
Delphi-Quellcode:
class procedure TThread.Synchronize(const AThread: TThread; AMethod: TThreadMethod);
var
  FSynchronize: TSynchronizeRecord;
begin
  FSynchronize.FThread := AThread; // da
  FSynchronize.FSynchronizeException := nil;
  FSynchronize.FMethod := AMethod;
  FSynchronize.FProcedure := nil;
  Synchronize(@FSynchronize);
end;

class procedure TThread.Synchronize(const AThread: TThread; AThreadProc: TThreadProcedure);
var
  FSynchronize: TSynchronizeRecord;
begin
  FSynchronize.FThread := AThread; // oder da
  FSynchronize.FSynchronizeException := nil;
  FSynchronize.FMethod := nil;
  FSynchronize.FProcedure := AThreadProc;
  TThread.Synchronize(@FSynchronize);
end;
und dann wird ein
Delphi-Quellcode:
TNotifyEvent
damit aufgerufen:
Delphi-Quellcode:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False; ForceQueue: Boolean = False);
var
  SyncProc: TSyncProc;
  SyncProcPtr: PSyncProc;
begin
  [...]
        if Assigned(WakeMainThread) then
          WakeMainThread(SyncProcPtr.SyncRec.FThread);
  [...]
end;
der bei einer VCL-Anwendung mit dieser Methode verbunden ist:
Delphi-Quellcode:
procedure TApplication.WakeMainThread(Sender: TObject);
begin
  PostMessage(Handle, WM_NULL, 0, 0);
end;
Wie man sieht, mit der schönen Instanz die mit Sender übergeben wird, wird schon mal gar nichts gemacht.
(BTW: Bei FMX sieht es auch nicht besser aus)

Fazit
Es ist völlig egal ob man dort eine Instanz des aktuellen Threads, oder irgendeine Instanz oder eine ungültige oder eben einfach gar keine mit
Delphi-Quellcode:
nil
übergibt. Somit besteht kein Grund zur Sorge, wenn jemand dort eine Instanz übergibt.

Darum sollte man hier auch ganz beherzt ein
Delphi-Quellcode:
nil
übergeben, denn das ist kürzer und gaukelt auch keine sonstige Funktionalität vor.

Hobbycoder 13. Nov 2018 16:44

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

Zitat von Delphi.Narium (Beitrag 1417950)
Zitat:

Zitat von Hobbycoder (Beitrag 1417947)
Hm...würde mir einer mal erklären, warum BeginUpdate und EndUpdate einer ListView nicht ausreichen, und zusätzlich noch das Minimize btw. Restore mehr Geschwindigkeit bringen soll?

Weil dann jegliche Aktuallisierung des Bildschirmes / der Anzeige wegfällt. Und das dauert unter Windows halt.

Ist 'ne langjährige praktische Erfahrung / Beobachtung, die man halt ausnützen kann, wenn was schneller gehen soll.

Ja, ist klar. Aber ist das nicht schon durch das ListView.BeginUpdate sichergestellt, dass aus diesem heraus keinerlei Zeichenvorgänge ausgelöst werden, solange ListView.EndUpdate nicht ausgeführt wird?

(Mal davon ausgehend, dass durch die Sammelroutine nicht noch andere Controls verändert werden).

Delphi.Narium 13. Nov 2018 17:10

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

Zitat von Hobbycoder (Beitrag 1417983)
(Mal davon ausgehend, dass durch die Sammelroutine nicht noch andere Controls verändert werden).

Aber genau dort scheint der Haken zu liegen.

Hab' letzlich ein Programm geschrieben, dass Textdateien einliest, daraus eine Wortliste erstellt, um diesen dann als 1:n-Beziehung in 'ne Datenbank zu schreiben (dient der schnellen Suche nach Inhalten, quasi sowas wie Google light für lokale Dateien). Die Datenbankinteraktion erfolgt ausschließlich über Select- und Insert-Statements per ExecSQL, also keine datensensitiven Controls.

Damit man was sieht, gibt es 'ne Progressbar, die halt alle 100 oder so ähnlich Statements eine Position weitergeht.

Sonst wird nix an der Oberfläche geändert.

Das Programm wird minimiert mindestens um den Faktor 10 schneller, auch dann, wenn ich auf die Progressbar verzichte.

Statusänderungen, Fortschrittsanzeige mache ich nun, in dem ich alle 100 Sätze den Application.Title, bei minimiertem Programm, ändere. Dann sieht man immernoch den Fortschritt, aber die Oberfläche bleibt unsichtbar. Damit ist es (warum auch immer) deutlich schneller.
Bei der großen Datenmenge, die zu verarbeiten ist, summiert sich das auf Laufzeitverkürzungen von vielen Stunden bis zu mehreren Tagen.

Vermutlich sollte man sowas dann direkt als Konsolenprogramm schreiben.

Uwe Raabe 13. Nov 2018 17:17

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

Zitat von Hobbycoder (Beitrag 1417983)
Aber ist das nicht schon durch das ListView.BeginUpdate sichergestellt, dass aus diesem heraus keinerlei Zeichenvorgänge ausgelöst werden, solange ListView.EndUpdate nicht ausgeführt wird?

Die ImageList-Changes z.B. gehen aber an dem BeginUpdate/EndUpdate vorbei und landen direkt im Control.

Uwe Raabe 13. Nov 2018 17:19

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

Zitat von Schokohase (Beitrag 1417981)
Du kannst da übergeben was du möchtest - der Wert wird im Prinzip nicht wirklich verwendet.

Für Synchronize stimmt das, aber bei Queue spielt es schon eine Rolle.

Hobbycoder 13. Nov 2018 17:27

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

Zitat von Delphi.Narium (Beitrag 1417990)
Zitat:

Zitat von Hobbycoder (Beitrag 1417983)
(Mal davon ausgehend, dass durch die Sammelroutine nicht noch andere Controls verändert werden).

Aber genau dort scheint der Haken zu liegen.

Damit man was sieht, gibt es 'ne Progressbar, die halt alle 100 oder so ähnlich Statements eine Position weitergeht.

Sonst wird nix an der Oberfläche geändert.

Gut. In dem Fall ist aber eben auch ein Control beteiligt, welches neu gezeichnet werden muss. Da ist das ja klar, dass das Zeit kostet. Und dann auch warum eine Minimize auch was bringt. Aber wenn eben kein weiteres Control beteiligt ist, sollte BeginUpdate reichen.

Zitat:

Zitat von Uwe Raabe (Beitrag 1417992)
Zitat:

Zitat von Hobbycoder (Beitrag 1417983)
Aber ist das nicht schon durch das ListView.BeginUpdate sichergestellt, dass aus diesem heraus keinerlei Zeichenvorgänge ausgelöst werden, solange ListView.EndUpdate nicht ausgeführt wird?

Die ImageList-Changes z.B. gehen aber an dem BeginUpdate/EndUpdate vorbei und landen direkt im Control.

Das ist natürlich schlecht. Würde es da nicht reichen, vor dem Begin im ListView die ImageList-Verbindung auf nil zu setzen und nach dem die ImageList alle benötigten Images enthält und alle ListItems erzeugt sind vor dem EndUpdate diese Verbinung wiederherzustellen?

EWeiss 13. Nov 2018 17:31

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

Darum sollte man hier auch ganz beherzt ein nil übergeben, denn das ist kürzer und gaukelt auch keine sonstige Funktionalität vor.
Da bin ich ja auf der richtigen Seite.. Ok bin raus.

gruss

Schokohase 13. Nov 2018 17:33

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

Zitat von Uwe Raabe (Beitrag 1417993)
Zitat:

Zitat von Schokohase (Beitrag 1417981)
Du kannst da übergeben was du möchtest - der Wert wird im Prinzip nicht wirklich verwendet.

Für Synchronize stimmt das, aber bei Queue spielt es schon eine Rolle.

Könntest du erklären wie oder welche Rolle? Ich sehe aktuell nicht, wo diese Information (Instanz von
Delphi-Quellcode:
TThread
) auch beim
Delphi-Quellcode:
TThread.Queue
sinnvoll verwendet wird.

Auch
Delphi-Quellcode:
TThread.Queue
ruft intern
Delphi-Quellcode:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False; ForceQueue: Boolean = False)
auf und das habe ich oben erläutert.

Aber bestimmt übersehe ich da etwas ...

KodeZwerg 13. Nov 2018 17:48

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

Zitat von Hobbycoder (Beitrag 1417995)
Das ist natürlich schlecht. Würde es da nicht reichen, vor dem Begin im ListView die ImageList-Verbindung auf nil zu setzen und nach dem die ImageList alle benötigten Images enthält und alle ListItems erzeugt sind vor dem EndUpdate diese Verbinung wiederherzustellen?

Guter Einfall, habs gerade getestet, vom Faktor Zeit ausgehend ist es gleich. Danke trotzdem!
Ich bin jetzt auf Hide und Show umgestiegen, das erspart dem Rechner eine Animation abzuspielen :-)

Uwe Raabe 13. Nov 2018 18:28

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

Zitat von Schokohase (Beitrag 1418001)
Könntest du erklären wie oder welche Rolle? Ich sehe aktuell nicht, wo diese Information (Instanz von
Delphi-Quellcode:
TThread
) auch beim
Delphi-Quellcode:
TThread.Queue
sinnvoll verwendet wird.

Auch
Delphi-Quellcode:
TThread.Queue
ruft intern
Delphi-Quellcode:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False; ForceQueue: Boolean = False)
auf und das habe ich oben erläutert.

Delphi-Quellcode:
TThread.Destroy
ruft
Delphi-Quellcode:
TThread.RemoveQueuedEvents
auf und dort werden alle noch nicht erledigten Queue-Events für diesen Thread gelöscht und somit nicht mehr ausgeführt. Übergibt man beim Queue ein nil, kommen die Events auch noch an wenn der auslösende Thread schon weg ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 Uhr.
Seite 1 von 2  1 2      

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