Einzelnen Beitrag anzeigen

UliBru

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

AW: Wie erzeugt man ein Event?

  Alt 20. Apr 2012, 09: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