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 Überlauf TMemo (https://www.delphipraxis.net/179070-ueberlauf-tmemo.html)

Jens Hartmann 12. Feb 2014 16:53

Überlauf TMemo
 
Hallo zusammen,

nur mal so eine Frage um einen eventuellen Fehler vorzubeugen. Wenn ich eine TMemo Komponenten habe, in die ich kontinuierlich Daten schreiben (Empfangen Daten einer Schnittstelle). Kann es dann sein, wenn das TMemo voll (max. Speicherkapazität erreicht) ist, das es dann zu einem Überlauffehler oder ähnlich kommt.

Eine Idee zum vorbeugen, wäre eventuell eine Art Ringspeicher in das TMemo zu bauen. Soll heißen, wenn z.B. 2000 Zeilen im Memo stehen, dann lösche die erste und füge wieder an.

Delphi-Quellcode:

if TMemo.Lines.Count >= 2000 then TMemo.Lines.Delete[0]
Ich bin mir allerdings nicht genau sicher wie die Grenzen von TMemo sind, bzw. welche Auswirkungen diese Situation hätte.

Vorab Danke und Gruß

Jens

p80286 12. Feb 2014 17:07

AW: Überlauf TMemo
 
Zum einen ist ein TMemo eigentlich nur für die Anzeige gedacht.
Wilst Du es oder eine TStringlist nutzen könntest Du z.B. ungefähr so vorgehen:

Delphi-Quellcode:
procedure Hinzufügen(Liste:tstrings;satz:string);
begin
  if Liste.count>Oberegrenze then
    Liste.delete(0);
  Liste.Add(satz);
end;
Besser wäre es gleich einen Ringpuffer zu nehmen. Ich meine hier hätte es schonmal was dazu gegeben im Zusammenhang mit Stack,FIFO usw., kann es aber nicht mehr wiederfinden.

Gruß
K-H

Popov 12. Feb 2014 17:42

AW: Überlauf TMemo
 
@Jens Hartmann

Also früher war die Grenze bei 64kByte, keine Ahnung seit welchem OS das nicht mehr ist. Zumindest bin ich früher dran gestoßen. Ich denke die Obergrenze dürfte die String-Größe sein, 100% sicher bin ich mir da aber nicht. Allerdings ist die Eigenschaft Text von TStrings ein String (bzw. das Ergebnis), also dürfte das stimmen.

Somit denke ich mir mal, dass if
Delphi-Quellcode:
TMemo.Lines.Count >= 2000 then TMemo.Lines.Delete[0]
nicht viel bringt, denn der Count ist nur der Count, und der ist Integer, also kann der Count theoretisch bis 2147483647 gehen. Vorher ist vermutlich die Kapazitätsgrenze des Strings erreicht.

Also ich würde die Länge von Text prüfen. Neigt sie ich der Obergrenze von Stringlänge, könnte man unten aufräumen. Aber Vorsicht! Man weiß ja nie wie viel Text dazu kommt.

Du könntest dir Capacity angucken, sie regelt den Puffer bei TStringList, evtl. auch
Delphi-Quellcode:
procedure TStringList.Grow;
, um zu sehen wie das regiliert wird.

hathor 12. Feb 2014 17:56

AW: Überlauf TMemo
 
Ein TMemo kann meines Wissens in neueren WINDOWS-Versionen ca. 2 GB groß werden.

Delphi-Quellcode:
const
  Memo1Limit = 10;

implementation

{$R *.dfm}

procedure TForm2.Memo1Change(Sender: TObject);
begin
  if Memo1.lines.Count > Memo1Limit then
    Memo1.Lines.Delete(0);
end;

Jens Hartmann 12. Feb 2014 19:09

AW: Überlauf TMemo
 
Zitat:

Zitat von P80286
Zum einen ist ein TMemo eigentlich nur für die Anzeige gedacht.

Ich nutze das ganze ja auch nur als Anzeige. Daher, sind die Daten nur von geringer Wichtigkeit. Ich möchte lediglich einen gewissen Zeitraum der vergangenen Daten sichtbar erhalten.

Die Lösung von:

Zitat:

Zitat von hathor
Delphi-Quellcode:
const
   Memo1Limit = 10;

implementation

{$R *.dfm}

procedure TForm2.Memo1Change(Sender: TObject);
begin
   if Memo1.lines.Count > Memo1Limit then
     Memo1.Lines.Delete(0);
end;


nutze ich ja bereits. Allerdings, wird das OnChange ja bei jeder Änderung des Inhaltes ausgelöst. Soll heißen, eine Zeile hat bei mir etwa 80 Zeichen. Davon möchte ich z.B. die letzten 2000 sichtbar erhalten. Daraus folgt...

Delphi-Quellcode:
if TMemo.Lines.Count >= 2000 then TMemo.Lines.Delete[0]
und das ins OnChange.

Nachteil: 80 Zeichen/Zeile -> 80 x OnChange ohne Sinn, Weiter gedacht: 80 Zeichen x 2000 Zeilen = 80.000 Zeichen -> 80.000 x OnChange, bis das erste mal die Funktion

Delphi-Quellcode:
TMemo.Lines.Delete[0]
ausgeführt wird. Nicht zu vergessen, die fehlenden Sonderzeichen wie Zeilenvorschub, Leerzeichen etc..

Sir Rufo 12. Feb 2014 19:30

AW: Überlauf TMemo
 
Wenn du die Werte direkt in das Memo schreibst und die überflüssigen Zeilen aus dem Memo löschst, dann benutzt du das Memo eben nicht nur zum Anzeigen, sondern auch zum Speichern der Daten.

Korrekterweise eben in eine StringList, diese anpassen und dann mit
Delphi-Quellcode:
Memo.Lines.Assign( LogStrings );
an das Memo durchreichen.

jaenicke 12. Feb 2014 19:45

AW: Überlauf TMemo
 
Ich würde wieder einmal eine TVirtualStringTree benutzen.

Das ist um Größenordnungen schneller als ein TMemo und auch viel einfacher als ständig den Text zu justieren, da du nur in OnGetText die passende Zeile zur Verfügung stellen musst. Außerdem sieht das für den Benutzer auch komisch aus, wenn er im Memo gerade scrollt und du dann etwas änderst.
Du kannst mit einer VirtualTree im Hintergrund auch einen schnellen Ringpuffer benutzen, wenn du nur einen Teil der Daten anzeigen willst.

Jens Hartmann 12. Feb 2014 21:35

AW: Überlauf TMemo
 
@Sir Rufo: Danke erstmal. Hab das ganze aktuell mal als Stringlist aufgebaut.

Delphi-Quellcode:
//Global
MemoBuffer : TStringList;

const
  MemoMaxLimit = 2000;

//im OnCreate der Form
MemoBuffer := TStringlist.Create;

//im OnDestroy
MemoBuffer.Free;

//In den erforderlichen Datenpacketen
UpdateStríngList('Datenpacket');

procedure TfMainVtServer.UpdateStringList(NewLine: string);
begin
  try
    MemoBuffer.Add(NewLine);
    if MemoBuffer.Count = MemoMaxLimit then
      begin
        MemoBuffer.Delete(0);
      end;
    mProtokoll.Lines.Assign(MemoBuffer);
  except
    on E: Exception do
    begin
      redtErrorMessages.Lines.Add(e.Message);
    end;
  end;
end;
funktioniert erst mal soweit ganz gut.

@jaenicke: Das mit vst ist eventuell auch ein Idee. Werde ich bei Gelegenheit mal ausprobieren. Allerdings, ist das Ding schon recht wuchtig für den Sinn den es erfüllen soll.

Trotzdem nochmal Danke...

Gruß Jens

Bummi 13. Feb 2014 06:41

AW: Überlauf TMemo
 
Listview und Listboxlassen sich ebenfalls virtuell betreiben OwnerData bzw. lbVirtual.

Furtbichler 13. Feb 2014 07:23

AW: Überlauf TMemo
 
Zitat:

Zitat von Sir Rufo (Beitrag 1247649)
Wenn du die Werte direkt in das Memo schreibst und die überflüssigen Zeilen aus dem Memo löschst, dann benutzt du das Memo eben nicht nur zum Anzeigen, sondern auch zum Speichern der Daten.

Ich finde, das ist genau anders herum: Indem ich die Zeilen rausschmeiße, verwende ich das Memo nur als vertikalen Lauftext oder 'TTY', also als Darstellungsparadigma einer Logs. Hmm. Noch noch einmal ein Zwitter, denn außer Darstellung geschieht ja nix. Aber ich weiß, worauf Du hinaus wolltest: '...direkt in das Memo schreibst...'.

Dein Ansatz würde bedeuten, das die Darstellung jeder neuen Zeile immer länger dauert, weil ja jedes Mal *alle* Zeilen erneut dem Memo zugewiesen werden.

Allgemein gesehen würde ich eine TLogFile-Komponente sehr praktisch finden, die alle Logausgaben speichert, aber nur die letzten N (z.B. =2000) zum Darstellen zur Verfügung stellt. Manchmal ist es doch wichtig, im Logfenster zu scrollen, um zu prüfen, was 'eben' (oder neulich) passiert ist.

Diese TLogFile-Komponente würde auch einem etwaigen Darsteller der Logausgaben per Event mitteilen können, das neue Daten zum Darstellen eingetroffen sind. Falls dies zu oft vorkommt (z.B. punktuell mehrere 1000 pro Sekunde), kann man das auch entprellen, d.h. maximal 10 Events pro Sekunde z.B. Wir hatten z.B. so ein Teil im Einsatz, das die Logausgaben mehrerer TCP-Clients verwaltet hat. Manchmal waren 20 TCP-Clients aktiv, mit 10-100 Logausgaben pro Sekunde (hoher Loglevel). Da fror dann die UI ein, weil die Events (wir haben Messages verwendet) den Messagebuffer einfach zugemüllt haben.

Diese Komponente wäre dann ein ViewModel zur Darstellung einer Logausgabe, und man könnte sowohl Jänicke als auch Bummi zufriedenstellen (oder mich mit meinem DevExpress-TcxGrid-Overkill).


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:01 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