AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Listen kontinuierlich aktualisieren

Ein Thema von michele_tedesco · begonnen am 1. Dez 2014 · letzter Beitrag vom 5. Dez 2014
Antwort Antwort
Seite 1 von 2  1 2   
michele_tedesco

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

Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 13:22
Hallo Zusammen

Ich habe eine Client/Server Anwendung von Delphi 2007 zu Delphi XE5 gezügelt.

Eine Client-Funktionalität erlaubt es mehrere "Listen-Forms" (Forms mit einer StringGrid) zu öffnen, welche über eine ClientSocket gespeist werden.
Jede Liste enthält ca. 5 Spalten. Die Daten werden einmalig pro Client beim Starten des Client in eine Array von Records Daten-Struktur geladen.

Die Forms, welche in einem Client geöffnet sind, werde in einer TList verwaltet.

Wenn nun über eine TCP-Nachricht der Server eine Nachricht sendet, werden alle Clients benachrichtigt. Jeder Client interpretiert die Nachricht und in einer Schlaufe aller geöffneten Forms (TList) werden alle StringGrids Zeile für Zeile aktualisiert.
Dieses Update passiert in Sekunden-Takt. Es werden in ca. 2 Stunden ca. 30'000-Einträge gemacht.

Bei 4 Clients mit je 5 göffneten Forms, sind es 20 Forms mit einer StringGrid die pro TCP Nachricht aktualisiert werden.

Wenn diese Clients auf D2007 kompiliert werden, dann kann es schon sein dass die CPU für 2,3 Mal 1-2 Sekunden 80-90% CPU Last erzeugen. Das ist immer dann, wenn am meisten TCP-Nachrichten dicht bei einander gesendet werden.

Wenn ich die selbe Anwendung nun auch DXE5 kompiliere, ergeben sich am Anfang die ähnlichen CPU-Peaks, nur erholt sich die CPU dann bis am Ende der Verarbeitung nicht mehr und die Clients sind dann "wie eingefroren". Da die CPU-Last so weit oben ist, dass das UI nicht mehr Antwort gibt.

Wie würde man solch ein Problem heute in Delphi XE5,6 oder 7 lösen?

Danke und Gruss
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#2

AW: Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 13:45
Optimierungspotential:
1. Die Nachrichtenverarbeitung per TCP im Hintergrund laufen lassen. Auch die Listen werden im Hintergrund aktualisiert, allerdings nicht(!) die Darstellung
2. Ein Timer aktualisiert z.B 2x pro Sekunde die Listen.
3. Die Listen sind gegen kongruete Zugriffe geschützt (TCritical Section)
4. Der Aktualisierungstimer wird nur gestartet, wenn die Liste verändert wurde.
5. Es werden nur die Zeilen im StringGrid aktualisiert, die sich auch verändert haben.
6. Aktualisierungen im StringGrid mit 'BeginUpdate'/'EndUpdate' umschließen.
7. Nur sichtbare Zeilen aktualisieren.
8. Statt StringGrid eine ListView (oder gleich ein VST) im virtual Mode nehmen.
Damit sollte die Skalierbarkeit deutlich erhöht werden.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.658 Beiträge
 
Delphi 7 Personal
 
#3

AW: Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 17:35
@Dejan Vu
Noch 11 und Du hast einen Grund zu feiern!

@michele_tedesco
abgesehen von den Vorschlägen, die Dejan Vu gemacht hat, sollte das Verhalten eigentlich gleich/ähnlich sein. Wie sieht es mit den Compilerschaltern aus (Range Check etc.)

Oder hast Du vielleicht zu viele (implizite) Wechsel/Konvertierungen zwischen AnsiString und (wide)String eingebaut?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
5.713 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 19:05
Nachdem ich bei der Suchmaschine meines Vertrauens einmal "delphi stringgrid beginupdate" eingegeben habe scheint es, dass der TStringGtrid selbst extrem langsam ist- Zumindest wenn man neue Zeilen hinzufügst.

Angeblich bringt es schon sehr viel, mittels einer WM_SETREDRAW das Ding einzufrieren und erst nachdem alles fertig ist wieder aufzutauen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.563 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 19:41
Nachdem ich bei der Suchmaschine meines Vertrauens einmal "delphi stringgrid beginupdate" eingegeben habe scheint es,
Das BeginUpdate ist dort auch besonders schön "versteckt".
http://www.delphipraxis.net/182881-c...ml#post1281804
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 21:41
@Dejan Vu
Noch 11 und Du hast einen Grund zu feiern!
Ich hab auch so einen Grund, zu feiern. Aber wie kommst Du auf 11?

Das Problem ist hier TCP bzw. das ständige Redraw der Grids.
Ich hatte Ähnliches mit 10 Threads, die einkommende TCP-Messages in 10 TMemos geloggt haben. Alles schön entkoppelt und ohne Synchronize, dafür mit Messages. Also imho optimal (halbwegs), jedenfalls besser als mit 'Synchronize' . Trotzdem fror die Anwendung immer wieder ein. Grund: Der Hauptthread wurde so dermaßen mit redraw-messages (und meinen eigenen) geflutet, das für normale Aktionen keine Zeit mehr war.

Ich habe dann einfach das ständige Aktualisieren der Memos deaktiviert. Wenn tausende Messages pro Sekunde ankommen, ist es doch wurscht, ob ich die alle sehe. Also: Daten in einen Ringbuffer und 2x pro Sekunde aktualisieren. Fertig.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Listen kontinuierlich aktualisieren

  Alt 1. Dez 2014, 21:53
Ja wie kommt der auf 11, wo es doch nur noch 10 sind
image.jpg
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: Listen kontinuierlich aktualisieren

  Alt 2. Dez 2014, 08:03
Noch ein paar sinnlose Beiträge mehr und ich kann mir endlich die Pappnase und das Hütchen aufsetzen
  Mit Zitat antworten Zitat
michele_tedesco

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

AW: Listen kontinuierlich aktualisieren

  Alt 4. Dez 2014, 09:14
Hallo Zusammen

@DejanVu und @himitsu, vielen Dank.
Ich habe bereits mehr als ein Optimierungschvorschlag eingebaut/umgebaut und es scheint schon Mal weniger Resourcen zu benutzen

Vorallem BeguinUpdate und der Aktualisierungs-Timer haben sehr geholfen!

Gruss
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.374 Beiträge
 
Delphi XE5 Professional
 
#10

AW: Listen kontinuierlich aktualisieren

  Alt 5. Dez 2014, 11:01
Client interpretiert die Nachricht und in einer Schlaufe aller geöffneten Forms (TList) werden alle StringGrids Zeile für Zeile aktualisiert.
Dieses Update passiert in Sekunden-Takt. Es werden in ca. 2 Stunden ca. 30'000-Einträge gemacht.
Klingt nach vielen Daten...

Denk mal über einen Ansatz nach, dass *nur* die Änderungen möglichst kompakt übertragen werden.
Wenn du für jede Zeile ein TCP-Paket schickst, wird das sicherlich viel unnötigen Traffic machen.

Vorschlag:
Serverseitig machst du an jedem Datensatz Integer-Feld dran - nennen wir es Transaktion.
Der Server hat eine Transaktionsnummer. Immer wenn eine Aktualisierung an Daten durchgeführt wird, wird anschließend diese Nummer erhöht.
Die aktuelle Nummer wird an allen *veränderten* Datensätzen in das neue Feld geschrieben.

Startet nun ein Client, sagt er dem Server gibt mir alle Zeilen welche eine Transaktionsnummer größer 0 haben. Dieses entspricht einen vollen Ladevorgang -> Erstbefüllung.

Die höhste Transaktionsnummer der Daten merkt sich der Client.

Bei den nächsten (Teil-) Aktualisierung fragt der Client den Server nach allen Datensätzen/Zeilen die eine Transaktionsnummer haben, welche größer als die gemerkte ist.

Mit dieser Technik kannst du nur Teile übertragen und die Pakete etwas effizienter Nutzen.
Der Client muss weniger Daten verarbeiten, da nicht immer ein Full-Update durchgeführt wird.
Wenn keine Daten verändert wurden, werden keine Daten übertragen.

Alternativ könnte man über Multicast, MessageQueues nachdenken.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/channel/UCUG...aXLclwO9qA-lzA

Geändert von generic ( 5. Dez 2014 um 11:03 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

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 +2. Es ist jetzt 15:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf