Entwickler-Ecke
Windows API - TObject per Sendmessage versenden
Gausi - Do 28.06.07 20:41
Titel: TObject per Sendmessage versenden
Ich bin mir nicht sicher, ob das so geht, und bevor ich anfange das lang zu coden, frag ich lieber mal.
Also. Ich habe eine Klasse, die im wesentlichen eine große TObjectlist enthält. Ich möchte nun diverse Objekte aus dieser Liste suchen. Das kann relativ lange dauern, daher möchte ich die Suche in einen Thread auslagern. D.h. die Klassenmethode .Suche wird in einem separaten Thread ausgeführt. Jetzt soll im Fenster sofort angezeigt werden, wenn das erste passende Objekt gefunden wurde. Würde über Synchronize gehen, aber das dauert erfahrungsgemäß zu lange, wenn viele Objekte gefunden werden. Außerdem möchte ich in der Klasse selbst die VCL rauslassen, d.h. TThread möchte ich nicht verwenden.
Meine Idee ist, das über Messages zu realisieren. D.h
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var aObject: TMyObject; aObject := MeinTollesGefundenesObject; SendMessage(MainWindow, WM_OBJECTGEFUNDEN, wParam(aObject), 0);
var newObject: TMyObject; case Message.msg of WM_OBJECTGEFUNDEN: begin newObject := TMyObject(wParam); DoSomething(newObject); end; |
Frage: Geht das? Kann der Sender einfach das Object in den Parameter packen, und kann der Empfänger das zurückcasten? Einfach ausprobieren is irgendwie nicht - gerade wenn Threads im Spiel sind, kann das ja zufällig gutgehen, bis es irgendwann kracht ;-). Das ganze soll nur Anwendungsintern passieren.
MrSaint - Do 28.06.07 20:51
Das geht gut, solange du in einem prozess bleibst (was du ja aber tust: du benutzt ja threads und kommunizierst nicht zw. prozessen). Deshalb wird alles im gleichen virtuellen Speicher"raum" ausgwführt und deshlab kannst du problemlos drauf zugreifen. Du solltest das gefundene Objekt nur nachem du die Message gesendet hast im Thread nicht mehr anfassen, da es dann zu bösen Fehlern kommen könnte (genauso: wenn der Thread läuft darfst du aus dem Hauptprogramm nicht drauf zugreifen). Hier hilft evtl. eine TCriticalSection. U.U. geht es sogar so:
Delphi-Quelltext
1: 2: 3:
| MeinObjekt.CriticalSection.Acquire; MeinObjekt.CriticalSection.Release; |
Dass also dein Objekt seine CriticalSection gleich mitnimmt. Lesender Zugriff auf das Objekt sollte problemlos funktionieren, nur wenn jetzt der Thread und/oder das Hauptprogramm anfängt in dem Objekt rumzuschreiben wirds kritisch (-> CriticalSection). U.U. kannst du das ja auch direkt in dein Objekt reinimplemeniteren, dass praktisch bei jeder Set-Methode erst mal die CriticalSection geholt wird und danach wieder freigegeben wird. Das wäre dann sogar komfortabel :)
MrSaint
Gausi - Do 28.06.07 21:16
Geschrieben wird an den versendeten Objekten nichts. Die werden bei Programmstart einmal initialisiert, und nur bei sehr bestimmten Aktionen verändert. Da muss ich noch etwas aufpassen, dass sich keine zwei Threads in die Haare kriegen können, aber das wird schon klappen.
Hier gings mir nur um die Frage, ob das Senden so klappt - und das scheint ja so zu sein :D.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!