Autor Beitrag
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 28.06.07 20:41 
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

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
 
// Thread-Code
var aObject: TMyObject;
//...
aObject := MeinTollesGefundenesObject;
SendMessage(MainWindow, WM_OBJECTGEFUNDEN, wParam(aObject), 0);

// VCL-Code
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.

_________________
We are, we were and will not be.
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: 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:

ausblenden Delphi-Quelltext
1:
2:
3:
MeinObjekt.CriticalSection.Acquire;
// irgendwas am Objekt verändern
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

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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.

_________________
We are, we were and will not be.