AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Synchronisierung asynchroner Kommunikation über Messages
Thema durchsuchen
Ansicht
Themen-Optionen

Synchronisierung asynchroner Kommunikation über Messages

Ein Thema von oXmoX · begonnen am 4. Feb 2006 · letzter Beitrag vom 6. Feb 2006
Antwort Antwort
oXmoX

Registriert seit: 8. Jun 2005
85 Beiträge
 
#1

Synchronisierung asynchroner Kommunikation über Messages

  Alt 4. Feb 2006, 12:25
Hi,

ich versuche gerade zwei Fenster, die über Messages miteinander kommunizieren, zu synchronisieren. Damit meine ich folgendes: Meine Anwendung schickt die Message "GET CALL xx PARTNER_HANDLE" an die andere Anwendung und diese sendet darauf (asynchron) die Antwort "CALL xx PARTNER_HANDLE yyyyyyy". Mein Problem besteht nun darin, eine Funktion
function GetPartnerhandle(Call: Integer): String zu bauen, die synchron ein Ergebnis zurückliefert. Die Funktion müsste also so lange warten, bis das Ergebnis vorliegt.

Hier ist mal mein Idee:

Delphi-Quellcode:
function MyClass.GetPartnerhandle(Call: Integer): String;
begin
  // SendMsg sendet die Message an die andere Anwendung.
  Self.SendMsg('GET CALL ' + IntToStr(Call) + ' PARTNER_HANDLE');
  repeat
    Sleep(50);
    Application.ProcessMessages;
  // LastMsg ist eine String-Variable, die immer die zuletzt erhaltene Message enthält.
  until (Pos('CALL ' + IntToStr(Call) + ' PARTNER_HANDLE', Self.LastMsg) > 0) or Application.Terminated;
  Result := Copy(Self.LastMsg, Pos('PARTNER_HANDLE', Self.LastMsg) + 15, 255);
end;
Leider bleibt meine Anwendung offenbar in der repeat-Schleife stecken, d.h. die Abbruchbedingung tritt nie ein. Mit anderen Worten: die Variable LastMsg, die sonst immer die zuletzt erheltene Message enthält, bleibt unverändert und daraus schließe ich, dass die Messages trotz "Application.ProcessMessages;" nicht mehr verarbeitet werden. ...warum nur?
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 4. Feb 2006, 18:35
Hi,
nun ja mit sleep legst du nun mal den ganzen Prozess schlafen. Das heißt natürlich auch, dass in der Zeit weder eine Message verarbeitet wird, noch dürfte sie empfangen werden.
Ich weiß natürlich nicht, um was für eine Art von Kommunikation es sich bei dir handelt, aber sieht auch nicht sehr Threadsafe aus. Würdest du auf CALL 1 und CALL 2 warten und 2 kommt kurz nach 1, könnte es sein, dass du 1 nie siehst oder ein falsches Ergebnis in 1 kopierst. Aber das ist eine andere Sache.

Definier dir ein Ereignis, dass speziell für das empfangen von einer Nachricht zuständig ist (ein Nachfahre von TEvent). Dann kannst du deine Schleife durch ein NachfahreVonTEvent.WaitFor(TimeOut) ersetzen. Dieses liefert dir dann entweder ein Timeout oder dass ein Signal empfangen wurde. Um das Signal zu senden, einfach NachfahreVonTEvent.setEvent aufrufen. (beide male als Instanz zu verstehen)

Hoffe das hilft,
Gruß Der Unwissende
  Mit Zitat antworten Zitat
oXmoX

Registriert seit: 8. Jun 2005
85 Beiträge
 
#3

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 4. Feb 2006, 22:31
Danke für deine Ratschläge, aber es will immernoch nicht funktionieren.
Meine Funktion sieht jetzt vorläufig in etwa so aus:
Delphi-Quellcode:
function MyClass.GetPartnerHandle(Call: Integer): String;
begin
  Self.SendMsg('GET CALL ' + IntToStr(Call) + ' PARTNER_HANDLE');
  repeat
    Self.FMsgEvent.WaitFor(INFINITE);
  until (Pos('CALL ' + IntToStr(Call) + ' PARTNER_HANDLE', Self.FLastMsg) > 0);
  Result := Copy(Self.FLastMsg, Pos('PARTNER_HANDLE', Self.FLastMsg) + 15, 255);
end;
FMsgEvent ist ein TEvent, dass immer ausgelöst wird (mit SetEvent), wenn eine neue Message der anderen Anwendung reinkommt. Es handelt sich übrigens um WM_COPYDATA-Nachrichten und die Prozedur, die diese entgegennimmt und daraufhin das Event auslöst, befindet sich in derselben Klasse (MyClass). Könnte es sein, dass der WaitFor-Aufruf die ganze Klasseninstanz lahmlegt, sodass auch keine Messages mehr entgegengenommen werden können?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 5. Feb 2006, 09:23
Guten Morgen, oXmoX.

Durch das Einstellen einer WM_COPYDATA Nachricht in die message queue der Anwendung A durch die Anwendung B kommt doch schon eine Kommunikation zwischen den Anwendungen zu Stande - wozu dann noch eine Kommunikation über kernel objects?

Echtzeit-Verarbeitung lässt sich durch die Verknüpfung der Techniken wohl nicht erreichen, da es passieren kann, dass die Nachricht WM_COPYDATA noch unbearbeitet in der queue steht, nachdem das event object in den signalled state versetzt wurde.

Außerdem macht die REPEAT-Schleife beim Warten keinen Sinn. Entweder du wartest INFINITE ohne Schleife oder du wartest mit TIMEOUT und Schleife. Im main thread ist das aber aus meiner Sicht eher ungeschickt. Wenn du mit kernel objects zur Prozess-Synchronisierung arbeitest, dann solltest du auch threads benutzen, damit das Konzept richtig zum tragen kommt.

Ich würde die Nachricht WM_COPYDATA im main thread verarbeiten. Wenn die Verarbeitung der übermittelten Daten eine Nebenläufigkeit bedingt, dann würde ich einen speziellen thread für diese Aufgabe einrichten, der dann aber auch über seine Methoden gesteuert werden kann.

Theoretische Grüße vom marabu
  Mit Zitat antworten Zitat
oXmoX

Registriert seit: 8. Jun 2005
85 Beiträge
 
#5

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 5. Feb 2006, 14:14
Hallo marabu!

Zitat von marabu:
Ich würde die Nachricht WM_COPYDATA im main thread verarbeiten. Wenn die Verarbeitung der übermittelten Daten eine Nebenläufigkeit bedingt, dann würde ich einen speziellen thread für diese Aufgabe einrichten, der dann aber auch über seine Methoden gesteuert werden kann.
Mein Ziel ist es ja eigentlich, die API von Programm B, die nur über WM_COPYDATA-Messages ansprechbar ist, in einer Klasse von Programm A zu kapseln, die völlig synchron - also über normale Methodenafrufe - arbeitet. Das bedeutet, dass der Main-Thread tatsächlich so lange warten muss, bis eine Antwort-Message von Programm B für den jeweiligen Funktionsaufruf eingetroffen ist (sonst wäre es ja nicht synchron). Daraus ergibt sich aber, dass das Empfangen der Messages nicht im Main-Thread stattfinden darf, denn dieser schläft ja, während er auf die Antwort wartet - kann also damit auch keine Messages mehr verarbeiten. Also muss ich wohl einen eigenen Thread einrichten, der nur für das Empfangen von Messages zuständig ist und den Main-Thread (z.B. über ein Event) bei Eintreffen einer Message ggfs. aufweckt. Die Alternative des Busy Waitings (so wie in meinem ursprünglichen Posting) will ich nach Möglichkeit vermeiden.

Ich arbeite zum ersten Mal mit Messages und auch mit Nebenläufigkeiten. Also sagt mir bitte bescheid, wenn ich da was falsch sehe. Kann man das so Umsetzen? Ist es möglich, einen Thread zu bauen, der völlig unabhängig vom Main-Thread Messages empfangen kann? Bin für jede Hilfe dankbar!

Gruß,
oXmoX
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#6

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 5. Feb 2006, 14:34
Da ist ein Denkfehler in deinen Überlegungen. Du darfst den main thread nie schlafen legen. Der ist für die Benutzerschnittstelle zuständig - und beinhaltet die message pump. Allerdings kannst du jederzeit Teile der Benutzerschnittstelle deaktivieren, wenn der Programmzustand das erforderlich macht.

Ich würde also die Nachrichten im main thread verarbeiten, und die eigentliche Arbeit von speziellen threads erledigen lassen, die ich nach dem Empfang bestimmter Nachrichten starte. Die Vorgehensweise wäre damit genau das Gegenteil zu deinen eigenen Überlegungen, aber auch so erreichst du eine Synchronisierung.

marabu
  Mit Zitat antworten Zitat
oXmoX

Registriert seit: 8. Jun 2005
85 Beiträge
 
#7

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 5. Feb 2006, 16:23
Zitat von marabu:
Ich würde also die Nachrichten im main thread verarbeiten, und die eigentliche Arbeit von speziellen threads erledigen lassen, die ich nach dem Empfang bestimmter Nachrichten starte. Die Vorgehensweise wäre damit genau das Gegenteil zu deinen eigenen Überlegungen, aber auch so erreichst du eine Synchronisierung.
D.h. also z.B., dass ich in meiner GetPartnerhandle-Methode einfach einen neuen Thread starte, der die Message an Anwendung B absendet, sich schlafen legt und dann beim Eintreffen der Antwort-Message durch den Main-Thread wieder aufgeweckt wird. Darauf wertet der neue Thread die Message aus und liefert ein entsprechendes Ergebnis zurück.

Ist es auf diese Weise Möglich, die GetPartnerhandleMethode als Funktion zu realisieren, die nach Ihrem Aufruf direkt das Anfrageergebnis zurückliefert? ...Ich zweifle irgenwie noch dran. ...Vermutlich hab ich dich nicht richtig verstanden. Ich schätze ich sollte mich jetzt erstmal noch ein wenig mit Threads beschäftigen. Wie gesagt: ist Neuland für mich.
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#8

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 5. Feb 2006, 16:42
Wenig bekannt ist, das sich auch WM_SETTINGSCHANGE aka WM_WININICHANGE zum Versenden eines Strings eignet.
Man muss die Message nur gezielt versenden, statt sie zu broadcasten und man sollte sie im OnMessage ausfiltern,
damit sich nicht einige Komponenten bemuessigt fuehlen ihre Systemdefaults neu einzulesen.

Das erlaubt es WM_COPYDATA freizuhalten fuer andere Zwecke.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 5. Feb 2006, 17:00
Zitat von oXmoX:
Ist es auf diese Weise Möglich, die GetPartnerhandleMethode als Funktion zu realisieren, die nach Ihrem Aufruf direkt das Anfrageergebnis zurückliefert? ...Ich zweifle irgenwie noch dran.
Gut dass du zweifelst. Die Nebenläufigkeit durch den von dir gestarteten thread macht eine synchrone Funktion GetPartnerHandle() im main thread - ohne busy waiting - unmöglich. Leider verstehe ich die Natur deines geplanten Programmes nicht so richtig, sonst könnte ich dir besseren Rat erteilen.

Zitat von Robert Marquardt:
Das erlaubt es WM_COPYDATA freizuhalten fuer andere Zwecke.
Hallo Robert, die Mütter von WM_COPYDATA haben das erste Doppelwort in COPYDATASTRUCT als Diskriminator vorgesehen. Die Zahl der Zwecke ist also nahezu unbegrenzt - vorausgesetzt man nutzt das feature auch.

Freundliche Grüße vom marabu
  Mit Zitat antworten Zitat
Lasse2002

Registriert seit: 29. Nov 2004
79 Beiträge
 
RAD-Studio 2009 Pro
 
#10

Re: Synchronisierung asynchroner Kommunikation über Messages

  Alt 6. Feb 2006, 14:08
Wenn du mit WaitFor auf einen Event wartest, dann legst du natürlich den ganzen Thread lahm. Es werden also auch keine Messages verarbeitet.

Ohne den Inhalt von Self.SendMsg zu kennen, tue ich mir allerdings recht schwer, dir einen guten Tip zu geben. Es gibt nämlich ganz verschiedene Funktionen, um eine Message an eine andere Anwendung zu verschicken. Je nachdem welche du verwendest, mußt du auch dementsprechend dein Programm anpassen...
Lasse
  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 04:48 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