![]() |
AW: Wie erzeugt man ein Event?
Der für mich oftmals entscheidende Vorteil von Messages ist, dass sie eine sehr lose Kopplung darstellen, und "Multicasting" ohne weiteres Zutun geht, da ohnehin an alle Top-Level Fenster verschickt wird. Da liegt aber auch einer der Nachteile: Wenn die verarbeitende Einheit nicht sinnvoll in "Fensternähe" passieren kann, muss man sich manuell ein Handle besorgen und die WndProc bauen.
Sobald Threads im Spiel sind, nehme ich die fast immer zur Kommunikation mit "aussen", vor allem weil man sonst auch gerne mal so Finten bekommt, dass man eine SQL-Connection eher unbemerkt in einem anderen Threadkontext benutzt als sie erstellt wurde (was meist schief geht). Andere Systemresourcen sind da ähnlich empfindlich, und durch die Messages ist der Kontext eindeutig. Wenn es nicht zu erwarten ist, dass ein Objekt mal Threadkontextübergreifend "quasseln" muss, greife ich aber genau so gerne zu den üblichen Eventhandlern (aka Methodenzeigern). Deren Vorteil liegt am ehesten noch im Übergeben von mehreren Parametern und ohne Rumgecaste. Letztlich ist das Argument "komfortabel bei Asynchronität" das schwerwiegendste bei Messages. |
AW: Wie erzeugt man ein Event?
Da der TE mit Delphi XE2 arbeitet bietet sich natürlich auch
![]() Und der Uwe hat dazu auch einen schönen ![]() |
AW: Wie erzeugt man ein Event?
Lauter interessante Vorschläge. Ich verwende nun Queue als vielleicht einfachste Lösung. Klar ist mir, dass die Verarbeitung im Main schnell genug sein muss bevor der nächste asynchrone Aufruf kommt. Dafür werkelt eben der Thread ungebremst vor sich hin.
Ich stell mal meine Lösung hier rein. Falls da noch etwas falsch sein sollte wäre ich für Hinweise dankbar. Ansonsten steht es als Muster zur Verfügung. Im der Main-Unit:
Delphi-Quellcode:
und dann in der Thread-Unit:
interface
type TMainForm = class(TForm) private ... public ... myThread: TmyThread; buffer: TmyBuffer; bufsize: integer; procedure OnBufferSwitch(buffer: tmyBuffer; bufidx: Integer); end; implementation procedure TMainForm.FormCreate(Sender: TObject); begin bufsize := ...; buffer := TmyBuffer.Create(bufsize); myThread := TmyThread.Create(true); //erst suspended myThread.Buffer := buffer; //Buffer übergeben myThread.FOnEvent := OnBufferSwitch; //Zuweisung Ereignisprozedur nun hier im Main myThread.FreeOnTerminate := true; myThread.Start; end; procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin myThread.Terminate; buffer.Free; end; procedure TMainForm.OnBufferSwitch(bufidx: Integer); begin DoSomething(buffer,bufidx); //Auswertung Datenpuffer end;
Delphi-Quellcode:
interface
type TOnBufferSwitch = procedure(bufidx: Integer) of object; type TmyThread = class(TThread) private fbuffer: tmyBuffer; foldbufidx: integer; fbufidx: integer; FCS: TCriticalSection; procedure AsyncBufferSwitch; protected procedure Execute; override; public FOnEvent: TOnBufferSwitch; property Buffer: tmyBuffer read fbuffer write fbuffer; property OnEvent: TOnBufferSwitch read FOnEvent write FOnEvent; constructor Create(suspended:boolean); reintroduce; destructor Destroy; override; end; implementation constructor TmyThread.Create(suspended:boolean); begin inherited Create(suspended); FCS := TCriticalSection.Create; end; destructor TmyThread.Destroy; begin FCS.Free; inherited; end; procedure TmyThread.Execute; var oldbufidx: integer; begin FOnEvent := MainForm.OnBufferSwitch; //Zuweisung Ereignisprozedur while not(Terminated) do begin CatchDriverData; //do something ... FCS.Enter; try foldbufidx := fbuffer.writebufidx; //aktueller Puffer fbuffer.Write(DriverDataArray, count); //inkl. autom. Umschaltung Pufferindex, wenn ein Puffer voll fbufidx := fbuffer.writebufidx; //neuer Pufferindex, falls umgeschaltet finally FCS.Leave; end; if bufidx <> oldbufidx then Queue(AsyncBufferSwitch); // <------ hier nun Queue anstelle von Synchronize sleep(10); end; end; procedure TmyThread.AsyncBufferSwitch; begin if Assigned(FOnEvent) then FOnEvent((fbufidx+1) and $1); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:34 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-2025 by Thomas Breitkreuz