全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2770
推到 Plurk!
推到 Facebook!

不在FORM中使用INDY,如何正确处理消息循环

答題得分者是:careychen
zhweizw
一般會員


發表:7
回覆:16
積分:9
註冊:2008-01-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-02-27 10:15:38 IP:222.187.xxx.xxx 訂閱
使用indy多年,一直把他放在FORM中使用,消息循环自然有FORM来处理。
但是今日突然想到不用FORM,如何处理消息呢。
自己写一个服务器端DEMO,下面的代码运行后,当有客户端连接时,能正确响应连接并自动创建子线程。但是仍然存在问题:
1、不能响应DisConnect()事件,客户端退出时,本服务器端创建的子线程没有退出。
2、响应ServerConnect()事件后,本程序占用CPU100%(拦截消息后发现,GetMessage()函数不停收到WM_TIME消息,就是他造成的CPU100%。

以上两个问题说明了消息循环不正确。是否需要自定义消息处理回调函数(CallBackFunction)?

请教达人帮忙完成代码,多谢。
-----代码如下----

program Project1;
uses
windows,
sysutils,
messages,
IdTCPServer,
IdThreadMgr,
IdThreadMgrDefault,
IdBaseComponent,
IdComponent;
type
TEvents = class
public
procedure ServerExecute(AThread :TIdPeerThread);
procedure ServerConnect(AThread :TIdPeerThread);
procedure ServerDisConnect(AThread :TIdPeerThread);
end;
var
Server:TIdTCPServer;
FThreadMgr:TIdThreadMgrDefault;
FEvents :TEvents;
Msg : TMsg;
procedure TEvents.ServerExecute(AThread :TIdPeerThread);
begin
end;
procedure TEvents.ServerConnect(AThread :TIdPeerThread);
begin
Messagebox(0,'Connect!','Info',MB_OK );
end;
procedure TEvents.ServerDisConnect(AThread :TIdPeerThread);
begin
Messagebox(0,'DisConnect!','Info',MB_OK );
end;

begin
//FEvents := nil;
Server := TIdTCPServer.Create(nil);
FThreadMgr := TIdThreadMgrDefault.Create(nil);
Server.ThreadMgr := FThreadMgr;
Server.DefaultPort := 47000;
Server.OnExecute :=FEvents.ServerExecute;
Server.OnConnect :=FEvents.ServerConnect;
Server.OnDisconnect := FEvents.ServerDisConnect;
Server.Active := True;
while GetMessage(Msg,0,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
conly_li
一般會員


發表:1
回覆:6
積分:1
註冊:2008-03-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-03-28 23:17:51 IP:222.72.xxx.xxx 訂閱
关注中,等待高手支招
------
我相信人与人之间一定有感应,有缘人一定能相遇,相识,相知!
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-07-12 23:30:32 IP:59.126.xxx.xxx 訂閱
HI~~, 其實最重要的原因是您的程序還沒寫完,所以會 CPU 滿載,請您在 OnExecute 的地方,加入讀取的指令,如 ReadLn 之類,就行了,會滿載是因為他的 Buffer 中咬著由 Client 送來的Data,一直無法釋放的關係。而且當您有正常的讀取後,當 Client 斷線時,就能正常的收到 Disconnect 訊息。本人是用 Indy 10 ,所以另貼程式碼如下

[code delphi]
program Project1;
uses
windows, IdContext, IdTCPServer, IdScheduler, IdSchedulerOfThread,
IdSchedulerOfThreadDefault, IdBaseComponent, IdComponent;

type
TEvents = class
public
procedure OnConnect(AContext: TIdContext);
procedure OnDisconnect(AContext: TIdContext);
procedure OnExecute(AContext: TIdContext);
end;

var
Server:TIdTCPServer;
FThreadMgr:TIdSchedulerOfThreadDefault;
FEvents :TEvents;
Msg : TMsg;

procedure TEvents.OnExecute(AContext: TIdContext);
begin
AContext.Connection.IOHandler.ReadLn;
end;

procedure TEvents.OnConnect(AContext: TIdContext);
begin
Messagebox(0,'Connect!','Info',MB_OK );
end;

procedure TEvents.OnDisconnect(AContext: TIdContext);
begin
Messagebox(0,'DisConnect!','Info',MB_OK );
end;

begin
Server := TIdTCPServer.Create(nil);
FThreadMgr := TIdSchedulerOfThreadDefault.Create(nil);
Server.Scheduler := FThreadMgr;
Server.DefaultPort := 47000;
Server.OnExecute :=FEvents.OnExecute;
Server.OnConnect :=FEvents.OnConnect;
Server.OnDisconnect := FEvents.OnDisconnect;
Server.Active := True;

while GetMessage(Msg,0,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.

[/code]
------
價值的展現,來自於你用哪一個角度來看待它!!
編輯記錄
careychen 重新編輯於 2008-07-12 23:33:27, 註解 無‧
pcplayer99
尊榮會員


發表:142
回覆:740
積分:591
註冊:2003-01-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-08-30 01:03:47 IP:121.34.xxx.xxx 訂閱
请教, Indy 10 稳定吗?我一直在用 9.018,似乎在稳定性方面还不错。

===================引 用 careychen 文 章===================
HI~~, 其實最重要的原因是您的程序還沒寫完,所以會 CPU 滿載,請您在 OnExecute 的地方,加入讀取的指令,如 ReadLn 之類,就行了,會滿載是因為他的 Buffer 中咬著由 Client 送來的Data,一直無法釋放的關係。而且當您有正常的讀取後,當 Client 斷線時,就能正常的收到 Disconnect 訊息。本人是用 Indy 10 ,所以另貼程式碼如下

[code delphi]
program Project1;
uses
windows, IdContext, IdTCPServer, IdScheduler, IdSchedulerOfThread,
IdSchedulerOfThreadDefault, IdBaseComponent, IdComponent;

type
TEvents = class
public
procedure OnConnect(AContext: TIdContext);
procedure OnDisconnect(AContext: TIdContext);
procedure OnExecute(AContext: TIdContext);
end;

var
Server:TIdTCPServer;
FThreadMgr:TIdSchedulerOfThreadDefault;
FEvents :TEvents;
Msg : TMsg;

procedure TEvents.OnExecute(AContext: TIdContext);
begin
AContext.Connection.IOHandler.ReadLn;
end;

procedure TEvents.OnConnect(AContext: TIdContext);
begin
Messagebox(0,'Connect!','Info',MB_OK );
end;

procedure TEvents.OnDisconnect(AContext: TIdContext);
begin
Messagebox(0,'DisConnect!','Info',MB_OK );
end;

begin
Server := TIdTCPServer.Create(nil);
FThreadMgr := TIdSchedulerOfThreadDefault.Create(nil);
Server.Scheduler := FThreadMgr;
Server.DefaultPort := 47000;
Server.OnExecute :=FEvents.OnExecute;
Server.OnConnect :=FEvents.OnConnect;
Server.OnDisconnect := FEvents.OnDisconnect;
Server.Active := True;

while GetMessage(Msg,0,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.

[/code]
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-08-30 09:19:52 IP:218.210.xxx.xxx 訂閱
嗯,就我的使用【感覺】比 9 穩定,不過我學 9 的時候,那時候對  indy 不是很了解,
實作了一支程式不是很穩定,後來昇成 indy 10 ,重新再學一次 (個人自己再重看一次) ,
後來新的專案就相當的穩定,不過那是站上的大大們幫忙,
但因為 indy 9 昇級成 indy 10 要……特別的有耐心哦

第一、indy 10 支援 .net 系統,indy 9 不支援
第二、程式碼30~40% 以上會異動
第三、一旦昇級後.... 請另準備一個開發環境裝 indy 9 ,不然 indy 9 、10 的元件是不相容的,無法在同一台執行!!
那你之前的專案就無法維護了!!
------
價值的展現,來自於你用哪一個角度來看待它!!
編輯記錄
careychen 重新編輯於 2008-08-30 09:21:45, 註解 無‧
系統時間:2017-12-16 13:08:38
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!