我有一个小型的客户端 - 服务器应用程序,其中服务器使用命名管道向客户端发送一些消息。客户端有两个线程 - 主GUI线程和一个“接收线程”,它通过命名管道不断接收服务器发送的消息。现在每当收到一条消息时,我想发起一个自定义事件 - 但是,该事件不应该在调用线程上处理,而应该在主要的GUI线程上处理 - 而且我不知道该怎么做(以及是否甚至有可能)。德尔福 - 跨线程事件处理
这是我到目前为止有:
tMyMessage = record
mode: byte;
//...some other fields...
end;
TMsgRcvdEvent = procedure(Sender: TObject; Msg: tMyMessage) of object;
TReceivingThread = class(TThread)
private
FOnMsgRcvd: TMsgRcvdEvent;
//...some other members, not important here...
protected
procedure MsgRcvd(Msg: tMyMessage); dynamic;
procedure Execute; override;
public
property OnMsgRcvd: TMsgRcvdEvent read FOnMsgRcvd write FOnMsgRcvd;
//...some other methods, not important here...
end;
procedure TReceivingThread.MsgRcvd(Msg: tMyMessage);
begin
if Assigned(FOnMsgRcvd) then FOnMsgRcvd(self, Msg);
end;
procedure TReceivingThread.Execute;
var Msg: tMyMessage
begin
//.....
while not Terminated do begin //main thread loop
//.....
if (msgReceived) then begin
//message was received and now is contained in Msg variable
//fire OnMsgRcvdEvent and pass it the received message as parameter
MsgRcvd(Msg);
end;
//.....
end; //end main thread loop
//.....
end;
现在我希望能够创建事件处理程序作为TForm1类的成员,例如
procedure TForm1.MessageReceived(Sender: TObject; Msg: tMyMessage);
begin
//some code
end;
那会不会是在接收线程中执行,但在主UI线程中执行。我特别喜欢接收线程只是触发事件,并继续执行,无需等待事件处理程序方法的返回(基本上我需要类似.NET Control.BeginInvoke方法)
我真的是初学者这个(我试图在几个小时前学习如何定义自定义事件),所以我不知道这是否可能,或者我做错了什么,所以非常感谢您的帮助。
唉。同步暂停所有辅助线程,并在主线程的上下文中执行,这意味着它首先破坏了多线程的许多目的。有更好的方法比同步吨。不过,我没有投票给你,因为即使这是一个可怕的答案,它在技术上是一个有效的答案。 :-) – 2010-08-27 17:41:55
谁告诉你这个神话?同步不会阻止“所有”辅助线程。它只会阻塞从它被调用的线程,并且这是由于它的同步特性而发生的。但其他线程继续运行。 – 2010-08-27 18:03:50
是的,只有调用线程被阻塞。这不是最好的机制,但如果你知道它是如何工作的,你应该没问题。 – Runner 2010-08-27 18:20:36