AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wie erzeugt man ein Event?

Ein Thema von UliBru · begonnen am 19. Apr 2012 · letzter Beitrag vom 20. Apr 2012
Antwort Antwort
Seite 2 von 2     12   
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#11

AW: Wie erzeugt man ein Event?

  Alt 19. Apr 2012, 16:31
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

AW: Wie erzeugt man ein Event?

  Alt 19. Apr 2012, 22:34
Da der TE mit Delphi XE2 arbeitet bietet sich natürlich auch Delphi-Referenz durchsuchenTThread.Queue an als nicht-blockierende Alternative zu Synchronize.
Und der Uwe hat dazu auch einen schönen Artikel auf seiner Seite veröffentlicht, wie man sich sehr elegant die Zwischenvariable schenken kann.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
UliBru

Registriert seit: 10. Mai 2010
155 Beiträge
 
Delphi 11 Alexandria
 
#13

AW: Wie erzeugt man ein Event?

  Alt 20. Apr 2012, 10:23
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:
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;
und dann in der Thread-Unit:
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;
Er wollte so richtig in Delphi einsteigen. Nun steckt er ganz tief drin ...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 08:32 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