![]() |
AW: Object mit SendMessage an MainThread senden
So hab ich es jetzt letztlich im Moment auch gelöst. Im MainTread eine Tobjectlist, vom Thread innerhalb ein TCriticalSection Daten hinzu, und per postmessage benachrichtigen.
Aber ich will mir auch nochmal die TThread.Queue anschauen, denn das find auch ganz interessant. |
AW: Object mit SendMessage an MainThread senden
Nein, SendMessage/PostMessage ist in Threads kein Problem.
Beides trägt die Message in den MessageQueue des Threads ein, in welchem die Komponente erstellt wurde, an die die Message geht. Verarbeitet wird die Message dann immer von der Messagebehandlung im zugehörigen Thread (meist der Hauptthread). TThread.Queue ist wie Synchronize, außer daß die Prozedur nicht sofort verarbeitet wird. (von dem "Bug" abgesehn, wenn man was vom MainThread aus daran übergibt) |
AW: Object mit SendMessage an MainThread senden
Zitat:
Zitat:
Zitat:
PostMessage, SendMessage usw geht in de Queue vom jeweiligem Thread. Überprüfen kannst Du, von welchem Thread die Funktion aufgerufen wird mit: GetCurrentThreadID Wenn ein eigener Thread wirklich seine Nachrichten auch behandeln will, sofern er überhaupt welche bekommt, dann mit PeekMessage, TranslateMessage in der Execute Schleife von TThread. |
AW: Object mit SendMessage an MainThread senden
Danke für die Aufklärung! War bisher zu faul das genauer zu testen. Das Problem was ich mal hatte wodurch ich dazu kam, war gelöst als ich noch eine ganze Menge mehr umgebaut habe. Das war dann also schon mal nicht der Suppenspucker.
|
AW: Object mit SendMessage an MainThread senden
Um noch einmal auf das Über- und Freigeben von Instanzen durch, von, über in Verbindung von Thread und Mainthread zu sprechen zu kommen ...
Was soll denn hier erreicht werden? Nehmen wir einmal das Beispiel mit
Delphi-Quellcode:
.
TLogMessage
Wir haben da also einen Thread, der irgendwas bearbeitet und zwischendurch immer wieder etwas melden soll. Dieser Thread soll aber durch das Senden dieser LogMessage nicht mehr als nötig ausgebremst werden (seine Hauptaufgabe besteht eben nicht im Versenden dieser LogMessage). Ok. Warum versendet dieser Thread diese LogMessage denn dann überhaupt? Geben wir diesem Thread doch einen Kumpel an die Hand, der dieses Versenden für ihn übernimmt. Und dieser Kumpel darf ja auch gerne wiederum ein Thread sein (macht ja nichts).
Delphi-Quellcode:
Dieser MessageService übernimmt die Verwaltung für die Message-Instanz, liefert diese Message per Synchronize an wen auch immer aus. Das hat aber dann mit dem eigentlichen Thread, der da am arbeiten ist schon nichts mehr zu tun.
type
TBaseMessage = class abstract end; TNotifyMessageEvent = reference to procedure( Sender : TObject; AMsg : TBaseMessage ); TMessageService = class( TThread ) private FCS : TCriticalSection; FEvent : TEvent; FMessages : TQueue<TBaseMessage>; <--- da kommen die rein FOnMessage : TNotifyMessageEvent; function GetOnMessage : TNotifyMessageEvent; procedure SetOnMessage( const Value : TNotifyMessageEvent ); procedure DoSendMessage( AMessage : TBaseMessage ); protected procedure Execute; override; procedure TerminatedSet; override; public constructor Create; destructor Destroy; override; procedure AddMessage( AMessage : TBaseMessage ); property OnMessage : TNotifyMessageEvent read GetOnMessage write SetOnMessage; end; constructor TMessageService.Create; begin inherited Create( False ); FCS := TCriticalSection.Create; FEvent := TEvent.Create( nil, False, False, '' ); FMessages := TObjectQueue<TBaseMessage>.Create; end; destructor Destroy; begin inherited; FMessages.Free; FEvent.Free; FCS.Free; end; function TMessageService.GetOnMessage : TNotifyMessageEvent; begin FCS.Enter; try Result := FOnMessage; finally FCS.Leave; end; end; procedure TMessageService.SetOnMessage( const Value : TNotifyMessageEvent ); begin FCS.Enter; try FOnMessage := Value; finally FCS.Leave; end; end; procedure TMessageService.AddMessage( AMessage : TBaseMessage ); begin FCS.Enter; try FMessages.Enqueue( AMessage ); FEvent.SetEvent; // <-- Den MessageService aufwecken finally FCS.Leave; end; end; procedure function TMessageService.GetOnMessage : TNotifyMessageEvent; begin FCS.Enter; try Result := FOnMessage; finally FCS.Leave; end; end; procedure TMessageService.TerminatedSet; begin inherited; FEvent.SetEvent; end; procedure TMessageService.DoSendMessage( AMessage : TBaseMessage ); var LOnMessage : TNotifyMessageEvent; begin LOnMessage := OnMessage; if Assigned( LOnMessage ) then LOnMessage( Self, AMessage ); end; procedure TMessageService.Execute; var LMessage : TBaseMessage; begin inherited; while not Terminated do begin FEvent.WaitFor; // Wir warten, bis sich was tut if not Terminated then begin // Nachricht aus der Queue holen FCS.Enter; try LMessage := FMessages.Extract; // Wenn noch Nachrichten in der Queue sind, dann den Event wieder setzen if FMessages.Count > 0 then FEvent.SetEvent; finally FCS.Leave; end; // Nachricht versenden Synchronize( procedure begin DoSendMessage( LMessage ); end ); // Nachricht freigeben LMessage.Free; end; end; Schon ist der Drops gelutscht und jeder macht nur ein wenig und nicht alles oder kreuz und quer durcheinander gewürfelt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 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 by Thomas Breitkreuz