AGB  ·  Datenschutz  ·  Impressum  







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

Aktualisierung und SendMessage

Ein Thema von yogie · begonnen am 26. Okt 2013 · letzter Beitrag vom 28. Okt 2013
Antwort Antwort
yogie

Registriert seit: 11. Sep 2003
Ort: bei Goslar
213 Beiträge
 
Delphi 6 Professional
 
#1

Aktualisierung und SendMessage

  Alt 26. Okt 2013, 11:26
Hallo zusammen,

ich beobachte folgenden Sachverhalt:

Von einer ersten Form (TDataModule) übertrage ich per SendMessage Daten zu einer anderen Form und lasse dort ein Element (z.B. Edit) aktualisieren. Sobald ich die Form verschiebe wird die Aktualisierung unterbrochen und läuft erst weiter wenn ich die Verschiebung beende. Mir ist schon klar, dass es an der Unterbrechung der Message-Loop liegt, aber eine richtig befriedigende Erklärung habe ich nicht. Weiterhin habe ich den Eindruck, dieses Verhalten ist nicht bei allen Objekten gleich und ich meine es hängt auch noch vom Betriebssystem ab (das geht jetzt zurück bis WIN95).

In der realen Anwendung soll die erste Form (TDataModule) Informationen über eine serielle Schnittstelle empfangen und sie dann an verschiedene Formen in der Anwendung verteilen. Bisher hatte ich dazu direkte Aufrufe von Prozeduren verwendet. Aus Gründen der besseren Trennung zwischen serieller Schnittstelle und div. Anzeigen wollte ich das jetzt ändern.

Ich wäre dankbar für eine Erklärung oder einen Tipp wie man es besser machen könnte.
Kompatibilität ist ein Euphemismus für n i c h t einhunderprozentige Austauschbarkeit
http://b-und-l-service.de/
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Aktualisierung und SendMessage

  Alt 26. Okt 2013, 11:44
Ich würde die Kommunikation asynchron per Thread machen und die graphische Aktualisierung synchronisieren. Das funktioniert auch beim Verschieben eines Fensters problemlos, zumindest unter Windows 8. Testbeispiel von mir eben (nicht schön, nur zum Test):
Delphi-Quellcode:
type
  TTest = class(TThread)
  protected
    procedure Execute; override;
  end;

  TForm18 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form18: TForm18;

implementation

{$R *.dfm}

procedure TForm18.Button1Click(Sender: TObject);
begin
  TTest.Create(False);
end;

{ TTest }

procedure TTest.Execute;
begin
  while not Terminated do
  begin
    TThread.Synchronize(nil, procedure
      begin
        Form18.Canvas.LineTo(Random(Form18.ClientWidth), Random(Form18.ClientHeight));
      end);
    Sleep(100);
  end;
end;
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
yogie

Registriert seit: 11. Sep 2003
Ort: bei Goslar
213 Beiträge
 
Delphi 6 Professional
 
#3

AW: Aktualisierung und SendMessage

  Alt 27. Okt 2013, 08:45
@jaenicke

Danke erstmal für den Tip.

Zwei Dinge dazu
- kann es sein, dass im Beispiel die Zeilen im Execute etwas durcheinander geraten sind?
so kann ich es jedenfalls in Delphi6 nicht machen,
ich habe es dann etwas umgebaut und zum Laufen gebracht ...

- das Problem mit der hängenden Aktualisierung läßt sich damit prima umgehen
mir geht es aber zusätzlich um eine Entkopplung zwischen der Empfänger-Form für
die seriellen Daten und den anderen Fenstern, die die Anzeigen machen.
ich habe in der Empfängerform zur Zeit eine Liste (TList) in der ich alle Anzeigefenster speichere,
bei neu einlaufenden Daten gehe ich diese Liste durch und schicke allen sichbaren Fenstern
die neuen Daten (SendMessage)

Ich habe festgestellt, dass SendMessage recht zeitaufwendig ist. Daher suche ich eine bessere
Lösung
Kompatibilität ist ein Euphemismus für n i c h t einhunderprozentige Austauschbarkeit
http://b-und-l-service.de/
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Aktualisierung und SendMessage

  Alt 27. Okt 2013, 15:58
- kann es sein, dass im Beispiel die Zeilen im Execute etwas durcheinander geraten sind?
so kann ich es jedenfalls in Delphi6 nicht machen,
Stimmt, anonyme Methoden gibt es erst ab Delphi 2009.

mir geht es aber zusätzlich um eine Entkopplung zwischen der Empfänger-Form für
die seriellen Daten und den anderen Fenstern, die die Anzeigen machen.
ich habe in der Empfängerform zur Zeit eine Liste (TList) in der ich alle Anzeigefenster speichere,
Genau dafür kannst du das nutzen. Du kannst dem Thread Bescheid geben und der verteilt die Aktualisierungen asynchron weiter an die weiteren Anzeigen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#5

AW: Aktualisierung und SendMessage

  Alt 28. Okt 2013, 01:02
Ich habe festgestellt, dass SendMessage recht zeitaufwendig ist. Daher suche ich eine bessere
Lösung
SendMessage() ist nicht per se langsam, sondern es wartet auf das Ende der vom Empfänger durchgeführten Aktion. Das asynchrone äquivalent dazu ist PostMessage() - das wartet nicht.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Aktualisierung und SendMessage

  Alt 28. Okt 2013, 05:37
Nur als Hinweis, falls es relevant sein sollte: PostMessage geht nur, wenn man die Daten nach dem Abschicken nicht wieder freigibt, da die Abarbeitung später passiert.

Eine Trennung der Steuerung der GUI von der Datenverwaltung und auch der einzelnen Fenster untereinander hielte ich aber für sinnvoller als ein Fenster direkt mit den anderen Fenstern via Messages kommunizieren zu lassen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#7

AW: Aktualisierung und SendMessage

  Alt 28. Okt 2013, 07:13
Wir hatten mal eine ähnliche Anwendung. Dort sind Daten von Messgeräten eingetroffen, sollten in die DB und parallel dazu angezeigt werden.

Wir haben es mit Threads und Messages (PostMessage) ausprobiert. Beides funktioniert gleich gut. In meinem Hinterkopf trällert aber immer noch, das man nicht mit Threads nicht um sich werfen sollte. Das kann ein Überbleibsel aus der der Steinzeit sein, aber ich finde Threads hierfür einfach oversized.

Ich würde zunächst das Observer-Pattern einführen, um Datenempfang und Visualisierung auch logisch zu entkoppeln und skalierbar zu machen.

Der Datenempfang implementiert einen Observer, an dem sich Formulare, die Daten anzeigen wollen, anmelden können.
Die Observerbenachrichtigungsschleife ist als Job eines Workerthreads implementiert, der wiederum eine Jobliste (=Queue) abarbeitet. So kann dieser Workerthread (besser : Pool) beliebige Jobs abarbeiten und das System kommt auch bei kurzzeitiger Überlastung nicht ins Schwitzen. Selbst wenn kurzzeitig sehr viele Benachrichtungen anstehen, blockiert der Observer nicht, da dann eben die Jobliste etwas voll wird...

Die Benachrichtigung an die einzelnen Subscriber (=Forms) kann nun als Postmessage verschickt werden. Das ist imho leichtgewichtiger als noch einen Thread zu starten. Allerdings sind dabei die Einschränkungen von Sebastian zu beachten. Man kann hier die Daten z.B. in eine Datenklasse mit Referenzzählung wrappen (Stichwort: Interface) oder Strings verwenden (z.B. bei einem Logger), der die Referenzzählung auch eingebaut hat.

Das generelle Problem ist hier, das bei Überlastung die Messagequeue der einzelnen Subscriber zu voll werden könnte. Das muss man im Einzelnen bewerten, ob das eine Rolle spielt und wie man damit umgehen kann bzw. soll.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Aktualisierung und SendMessage

  Alt 28. Okt 2013, 08:59
In meinem Hinterkopf trällert aber immer noch, das man nicht mit Threads nicht um sich werfen sollte. Das kann ein Überbleibsel aus der der Steinzeit sein, aber ich finde Threads hierfür einfach oversized.
Ob der Overhead der Messagebehandlung da wirklich so viel geringer ist?

Messages sind jedenfalls gerade bei größerem Datenaufkommen ungeeignet, da alles über einzelne Nachrichtenwarteschlangen läuft. Wenn diese dann zu stark belastet werden, merkt man das an einer etwas träge auf Eingaben reagierenden Anwendung, da die dazu gehörenden Nachrichten entsprechend langsamer behandelt werden können. Zudem kann es sein, dass eine Nachricht länger braucht bis sie abgearbeitet wird und so die Aktualisierung aller Fenster laggt.

Davon ganz abgesehen kann man mit Messages erst einmal nur zwei Zahlenwerte schicken. Alles andere läuft dann als Pointer- und Speicherspielerei. Ein Thread hingegen kann typsicher und sauber direkt mit den Daten arbeiten, diese aufbereiten und gezielt an die passenden Empfänger weitergeben.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
yogie

Registriert seit: 11. Sep 2003
Ort: bei Goslar
213 Beiträge
 
Delphi 6 Professional
 
#9

AW: Aktualisierung und SendMessage

  Alt 28. Okt 2013, 19:37
vielen Dank!
Das ist genau die Art Beiträgen die mich weiterbringen.
(keine Ironie!!) Man ist als Einzelkämpfer immer dankbar,
wenn mal Anregungen mit einem anderen Blickwinkel kommen.
Sonst kopiert man nur immer wieder die Vorgehensweise,
die man schon vor 5 Jahren entwickelt hat.

@Furtbichler : Diese Ausführungen sind (zumindest für mich)
schon ein ziemlich großes Geschütz, trotden danke für die
ausfühliche Antwort. Ich werde das mal durchgehen und
schauen, was davon in meinem Fall verwertbar und macbar ist.

Für alle die es interessiert : Es werden Ströme und Spannungen
unter bestimmten Bedingungen gemessen (Elektrochemie, Potentiostaten)
Das Ganze findet eventuell auch noch auf mehreren Kanälen statt
und soll per serieller Schnittstelle (ev. Netzwertk) an einen
PC gekopplet werden.
Kompatibilität ist ein Euphemismus für n i c h t einhunderprozentige Austauschbarkeit
http://b-und-l-service.de/
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#10

AW: Aktualisierung und SendMessage

  Alt 28. Okt 2013, 19:52
Ob der Overhead der Messagebehandlung da wirklich so viel geringer ist?
...Messages sind jedenfalls gerade bei größerem Datenaufkommen ungeeignet
Kann ich nicht bestätigen. Bei einer Implementierung eines Loggers wurden auch mehrere Tausend Messages pro Sekunde nicht langsamer abgearbeitet als per Thread. Der Bottleneck war hier eindeutig die Darstellung (wie immer).

Geändert von Furtbichler (28. Okt 2013 um 19:55 Uhr)
  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 17:46 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