【发布时间】:2021-06-18 00:17:03
【问题描述】:
我在主线程中创建了两个 WndProc,然后我几乎同时从其他线程向每个线程发布消息,但从 WndProc1 开始。这个 WndProc1 有一项工作要持续一段时间……它在开始和结束时都会发出信号。 WndProc2 在被访问时也会发出信号。现在,当我按下按钮开始这个测试时,我得到:“P1-Enter ... [delay] ... P1-Leave WndProc2”。如您所见,第二条消息等待 WndProc1 完成,尽管他被发送到 WndProc2 !我想知道的是,如果这两个 WndProcs 没有共同点,这个序列化是如何工作的?我认为即使我有两个不同的组件,每个组件都有自己的 WndProc(但我没有检查),也会发生这种情况。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, SyncObjs;
type
TMyThread = class(TThread)
private
FHnd: HWND;
FTime: Integer;
protected
procedure Execute; override;
public
constructor Create(AHnd: HWND; ATime: Integer);
end;
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
TestHand1, TestHand2: HWND;
MyT1, MyT2: TMyThread;
protected
procedure TestWndProc1(var Msg: TMessage);
procedure TestWndProc2(var Msg: TMessage);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TMyThread.Create(AHnd: HWND; ATime: Integer);
begin
inherited Create;
FHnd:= AHnd;
FTime:= ATime;
end;
procedure TMyThread.Execute;
begin
Sleep(FTime);
PostMessage(FHnd, WM_USER, 0, 0);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TestHand1:= AllocateHWnd(TestWndProc1);
TestHand2:= AllocateHWnd(TestWndProc2);
end;
procedure TForm1.TestWndProc1(var Msg: TMessage);
var I: Integer;
A, B, C: Cardinal;
begin
if Msg.Msg = WM_USER then begin
Caption:= Caption + ' P1-Enter';
A:= $12345678; B:= $98765432;
for I:= 1 to 180000000 do begin
C:= A * B; B:= C * A; A:= B * C;
end;
Caption:= Caption + ' P1-Leave';
end;
end;
procedure TForm1.TestWndProc2(var Msg: TMessage);
begin
if Msg.Msg = WM_USER then
Caption:= Caption + ' WndProc2';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption:= '';
MyT1:= TMyThread.Create(TestHand1, 300);
MyT2:= TMyThread.Create(TestHand2, 350);
end;
end.
【问题讨论】:
-
确实消息是从消息队列中一一取回的。在处理您之前发布的消息之前,您稍后发布的消息将不会被检索和处理。如您所见,不同的窗口过程或不同的组件,它们的共同点是消息队列——它们存在于同一个线程中,因此共享同一个队列。
-
但这就是我不明白的......两个窗口过程(或更多)怎么会有相同的消息队列?
-
消息队列是线程而不是窗口的特性。见documentation。
-
不确定是否明显,您创建了不同的线程,但这些不同的线程发布到同一个(主/gui)线程(因为它们发布到的窗口是由主线程创建的)。跨度>
标签: multithreading delphi message