![]() |
CPU 100% bei mehreren StringGrid-Forms
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 = '#STNR' THEN BEGIN Str := IntToStr(AktPtr^.Stnr); END (* if *) ELSE IF FeldCode = '#NAME' THEN BEGIN IF DatenOk AND (FormInfoMain.Kategorie.GetKatTyp(DataRec.Kat) = 'S') THEN Str := GetDataFeld('Staffel') ELSE Str := DataRec.Name; END (* if *) ELSE IF FeldCode = '#JG' THEN BEGIN IF FormInfoMain.Kategorie.GetKatTyp(DataRec.Kat) = 'S' THEN 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; |
AW: CPU 100% bei mehreren StringGrid-Forms
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 :freak:, 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. ![]() |
AW: CPU 100% bei mehreren StringGrid-Forms
Hallo himitsu
Vielen Dank für dein Feeback zum Rendering. Ich habe das "Zeichnen" um ein Vielfaches (ca. 6-7) Mal schneller gemacht :dancer: Lösung war perfekt! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:21 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