我有一個小型的客戶端 - 服務器應用程序,其中服務器使用命名管道向客戶端發送一些消息。客戶端有兩個線程 - 主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