Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Nachrichtenverarbeitung zwischen Threads (https://www.delphipraxis.net/146550-nachrichtenverarbeitung-zwischen-threads.html)

R2009 22. Jan 2010 05:19


Nachrichtenverarbeitung zwischen Threads
 
Hi,

wir implementieren ein Nachrichtenaustausch zwischen 2 Threads mittels PostThreadMessage und einer
entsprechenden Auswertungsmethode in jedem Thread.

2 Probleme sind aufgetaucht:

1.) selbst beim einfachsten Thread funktioniert das nur wenn in der Hauptschleife des Thread
application.processmasseges steht.

2.) es funktioniert nur stablil wenn PostThreadMessage in einem Event, also in einem Timerevent oder
in einem Event einer seriellen Schnittstelle aufgerufen wird. Rufe ich PostThreadMessage im Thread
irgendwo sonst auf wird die Nachricht manchmal gesendet manchmal nicht. PostThreadMessage gibt jedesmal
true zurück, die Nachricht müsste also abgesetzt sein.

In dem Problemthread sind allerdings auch ein Timer (Delphi) und eine serielle Schnittstellenkomponente (Asynchpro)
implementiert. Klaut mir da jemand meine Messages?
Kann ich die Messageverarbeitung irgendwie erzwingen?

Grüsse
Rainer

PS: den Code kann ich hier nicht ablegen ist mittlerweile zu umfangreich.

sirius 22. Jan 2010 10:16

Re: Nachrichtenverarbeitung zwischen Threads
 
Delphi-Quellcode:
type

  TThread1 = class(TThread)
    public
      MainWnd:hwnd;
      otherThread:TThread;
      procedure Terminate;
    protected
      procedure execute; override;
  end;

  TThread2 = class(TThread)
    public
      MainWnd:hwnd;
      otherThread:TThread;
      procedure Terminate;
    protected
      procedure execute; override;
    private
      FTimer:TTimer;
      procedure TimerTimer(Sender:TObject);
  end;


  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    Thread1:TThread1;
    Thread2:TThread2;
    procedure ThreadMessage(var msg:TMessage); message WM_User;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TThread1 }

procedure TThread1.execute;
var msg:TMsg;
begin
  while getmessage(msg,0,0,0) do
  begin
    postmessage(MainWnd,WM_User,0,1);
    postThreadmessage(otherThread.ThreadID,WM_user,0,0);
    Dispatchmessage(msg);
  end;
end;

procedure TThread1.Terminate;
begin
  inherited;
  PostThreadMessage(ThreadID,WM_Quit,0,0);
end;

{ TThread2 }

procedure TThread2.execute;
var msg:TMsg;
begin
  FTimer:=TTimer.Create(nil);
  FTimer.Interval:=1000;
  FTimer.OnTimer:=TimerTimer;
  FTimer.Enabled:=true;
  while getmessage(msg,0,0,0) do
  begin
    postmessage(MainWnd,WM_User,0,2);
    Dispatchmessage(msg);
  end;
end;

procedure TThread2.Terminate;
begin
  inherited;
  PostThreadMessage(ThreadID,WM_Quit,0,0);
end;

procedure TThread2.TimerTimer(Sender: TObject);
begin
  postmessage(MainWnd,WM_user,0,0);
  PostThreadMessage(otherThread.ThreadID,WM_User,0,0);
end;

{ TForm1 }

procedure TForm1.ThreadMessage(var msg: TMessage);
begin
  memo1.lines.add(inttostr(msg.lparam));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Thread1:=TThread1.Create(true);
  Thread2:=TThread2.Create(true);
  Thread1.otherThread:=Thread2;
  Thread2.otherThread:=Thread1;
  Thread1.MainWnd:=handle;
  Thread2.MainWnd:=handle;
  Thread1.Resume;
  Thread2.Resume;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Thread1.Terminate;
  Thread2.Terminate;
  Thread1.WaitFor;
  Thread2.WaitFor;
  Thread1.Free;
  Thread2.Free;
end;
Funktioniert. :gruebel:

mjustin 22. Jan 2010 11:23

Re: Nachrichtenverarbeitung zwischen Threads
 
Zitat:

Zitat von sirius

Delphi-Quellcode:
  Thread1.Resume;
  Thread2.Resume;
Funktioniert. :gruebel:

TThread.Resume (und Suspend) sind nun in Delphi 2010 'deprecated' (wegen möglicher Probleme mit dem bisherigen Code):

http://stackoverflow.com/questions/1...-used-in-place

Jaja, der Fortschritt ... :)

Michael

sirius 22. Jan 2010 16:17

Re: Nachrichtenverarbeitung zwischen Threads
 
Na dann halt TThreadx.Start.

Ist nur die Frage, ob dann intern der Stread erst bei start initialisiert wird und damit davor noch keine ThreadID existiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:49 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