AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

CPU 100% bei mehreren StringGrid-Forms

Ein Thema von michele_tedesco · begonnen am 23. Nov 2014 · letzter Beitrag vom 1. Dez 2014
Antwort Antwort
michele_tedesco

Registriert seit: 19. Mär 2014
50 Beiträge
 
#1

CPU 100% bei mehreren StringGrid-Forms

  Alt 23. Nov 2014, 21:07
Hallo Zusammen

Beim Übernehmen einer Delphi2007 Anwendung habe ich ein Problem in XE5, welches ich nicht nachvollziehen kann.

Die Anwendung soll ermöglichen mehrere Formulare zu öffnen, welche eine Liste beinhaltet (StringGrid).
Die alle Listen aller Formulare werden bei einem Client-TCP-Read event aktualisiert.

Die Formulare werden in einer TList geführt und in einer Schlaufe aktualisiert.

Wenn ich 10 solche Anwendungen mit je einer Liste von 10 Forms (also 100 Forms) auf meinem Server starte (Remote Application), dann ist di CPU-Last ca. 40-60%.

Wenn ich die genau gleiche Anwendung in Delphi XE5 kompiliere und im selben (100 Forms) Setup starte, dann ist die CPU immer bei 100%.

Ich habe zuerst die Anwendung in XE5 OHNE das updated der GridLists kompiliert und die CPU-Last ist bei ca. 20%.
Mit dem Zeichnen der GridList eben 100%.

Ich gehen Zeile für Zeile, Zelle für Zelle durch und setzte mit GridList.Cells[] den Wert, welcher aus der TCP Nachricht ankommt.

Gibt es einen markanten Unterschied im "Rendern" der GridList zwischen den beiden Delphi Versionen?

Ich habe auch nach jeder TCP-Nachricht eine Application.ProcessMessages; ergänzt, jedoch hilft das zwar die Listen abzufüllen, die Applikation ist weiterhin nicht bedienbar und die CPU-Last fast immer bei 100%.


Hier die ein Teil der Methode zum Aktualisieren des Forms:
Delphi-Quellcode:
procedure TFormInfoZeit.FormUpdate;
VAR AktPtr : PZeitRec;
    DataRec : TDataRec;
    PosRang : TRangSet;
    AllRang : TRangSet;
    SubName : STRING;
    IntData : TInternalData;
    Index : LONGINT;
    OverKat : LONGINT;
    FeldBreite : LONGINT;
    TotBreite : LONGINT;
    FeldNr : LONGINT;
    FeldCode : STRING;
    FeldSize : LONGINT;
    Select : BOOLEAN;
    DBFlag : BOOLEAN;
    Str : STRING;
begin
  (* Fenstergrösse *)
  GridList.Font.Size := CSizeFont [FontSize];
  GridList.DefaultRowHeight := CSizeHeight[FontSize];
  GridList.ColCount := MAX(GetFeldAnzahl,1);
  GridList.RowCount := AnzLine+1;

  (* Titelzeile *)
  TotBreite := 0;
  DBFlag := FormInfoMain.DBstaffel;
  FOR FeldNr := 1 TO GetFeldAnzahl DO BEGIN
    FeldBreite := ROUND(GetFeldSize(FeldNr)*CSizeWidth[FontSize]);
    GridList.ColWidths[FeldNr-1] := FeldBreite;
    GridList.Cells[FeldNr-1,0] := GetFeldBez(FeldNr);
    TotBreite := TotBreite+FeldBreite;
    FeldCode := GetFeldCode(FeldNr);
    IF StrLeft(FeldCode,1) <> '#THEN DBFlag := TRUE;
  END; (* for *)
  GridList.Width := TotBreite+GetFeldAnzahl+3;
  GridList.Height := ROUND(1.03*GridList.RowCount*GridList.DefaultRowHeight+17);
  Self.Height := GridList.Top+GridList.Height+28;
  Self.Width := Max(GridList.Left+GridList.Width+10,650);

  AktPtr := FormInfoMain.ZeitList;
  Index := 1;
  WHILE Index < GridList.RowCount DO BEGIN
    IF AktPtr <> NIL THEN BEGIN
      FormInfoMain.DataList_GetData(AktPtr^.Stnr,DataRec);
      IF (DataRec.Kat IN KatSet) AND (AktPtr^.ZeitNr IN PosSet) THEN BEGIN

        (* Ist Datensatz selektiert ? *)
        IF ShowKlausel <> NIL THEN BEGIN
          IF Daten <> NIL THEN Select := Klausel_Auswerten(Daten.DataSet,IntData,ShowKlausel)
                          ELSE Select := Klausel_Auswerten(NIL,IntData,ShowKlausel);
        END (* if *)
        ELSE Select := TRUE;

        (* alles ok *)
        IF Select THEN BEGIN

          (* alle Kolonnen durchlaufen *)
          FOR FeldNr := 1 TO GetFeldAnzahl DO BEGIN
            FeldCode := GetFeldCode(FeldNr);
            FeldSize := GetFeldSize(FeldNr);

            (* Standard-Felder *)
            Str := '';
            IF FeldCode = '#STNRTHEN BEGIN
              Str := IntToStr(AktPtr^.Stnr);
            END (* if *)
            ELSE IF FeldCode = '#NAMETHEN BEGIN
              IF DatenOk AND (FormInfoMain.Kategorie.GetKatTyp(DataRec.Kat) = 'S') THEN Str := GetDataFeld('Staffel')
                                                                                   ELSE Str := DataRec.Name;
            END (* if *)
            ELSE IF FeldCode = '#JGTHEN BEGIN
              IF FormInfoMain.Kategorie.GetKatTyp(DataRec.Kat) = 'STHEN
                Str := '--'
              ELSE IF AktPtr^.SubNr = 0 THEN BEGIN
                IF DataRec.Jg > 0 THEN Str := ZahlToStr(DataRec.Jg)
                                  ELSE Str := '??';
              END (* if *)
              ELSE Str := '--';
            END (* if *)
            (* Datenbank-Felder *)
            ELSE IF DBflag THEN BEGIN
              IF DatenOk THEN BEGIN
                IF StrLeft(FeldCode,1) = '#THEN Str := GetDataFeld(StrRight(FeldCode,2))
                                             ELSE Str := GetDataFeld(FeldCode);
              END (* if *)
              ELSE Str := StrFill('-',FeldSize);
            END; (* if *)

            (* Anzeigen *)
            GridList.Cells[FeldNr-1,Index] := Str;
          END; (* for *)
          (* nächste Zeile *)
          INC(Index);
        END; (* if *)
      END; (* if *)
      AktPtr := AktPtr^.Next;
    END (* if *)
    ELSE BEGIN
      GridList.Rows[Index].Clear;
      INC(Index);
    END; (* else *)
  END; (* for *)

  (* Titel setzen *)
  Caption := GetTextAlle('aktuelle Zeiten','temps actuels','tempi attuali','actual times');
  IF (StrLeft(Titel,1) = '/') OR (StrLeft(Titel,1) = '\') THEN
    Caption := Caption+' '+Titel
  ELSE IF Titel <> 'THEN
    Caption := Titel;
end;

Geändert von michele_tedesco (23. Nov 2014 um 21:17 Uhr) Grund: Code-Beispiel...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.016 Beiträge
 
Delphi 12 Athens
 
#2

AW: CPU 100% bei mehreren StringGrid-Forms

  Alt 23. Nov 2014, 21:36
BeginUpdate/EndUpdate?

Im TStringGrid (XE3) versteckt sich das als SetUpdateState, welches aber private ist und ich jetzt nicht fand, wie man das aufruft.
[edit] Habs gefunden, es geht über das BeginUpdate jeder/irgendeiner Row und wird dann zurck ans Grid weitergeleidet , also einfach auf das BeginUpdate der ersten Row losgehen.


Bei jeder einzelnen Zuweisung wird ein Neuzeichnen ausgelöst.
Das kann man optimieren, indem man ganze Zeilen/Rows auf einmal zuweist, oder eben das Update deaktiviert, solange man Vieles schnell zuweist.
http://www.delphipraxis.net/182865-s...palte-1-a.html
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (23. Nov 2014 um 21:40 Uhr)
  Mit Zitat antworten Zitat
michele_tedesco

Registriert seit: 19. Mär 2014
50 Beiträge
 
#3

AW: CPU 100% bei mehreren StringGrid-Forms

  Alt 1. Dez 2014, 13:07
Hallo himitsu

Vielen Dank für dein Feeback zum Rendering.
Ich habe das "Zeichnen" um ein Vielfaches (ca. 6-7) Mal schneller gemacht

Lösung war perfekt!
  Mit Zitat antworten Zitat
Antwort Antwort

 

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 05:03 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