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

再次問一個關于IDTcpServer的Execute的問題

答題得分者是:RaynorPao
zhgwbzhd
一般會員


發表:10
回覆:32
積分:18
註冊:2008-07-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-08-20 23:03:00 IP:221.218.xxx.xxx 未訂閱
作為服務耑,他可能是多個綫程在同時運行。
我在Execute中,會有一個死循環,在等待ado通道的準備。
例如:
while(...)
{
}

那么這些死循環會不會佔用大量的資源??用不用增加讓繫統接收消息的東西,應該加什么???
如果在其他的應用中,就可以加 Application->ProcessMessages();
但是在這裏加上之后,就會報錯。大意是“不知道是Application還是Svcmgr::Application”。

我剛剛做好的一個 service 程序,為何一起動CPU就100%,停止就沒事了。不知道在哪裏佔用暸如此的資源。
(我在ServiceExecute中增加一個sleep就不那么佔用CPU了,如果不加就佔100%,有什么方法不用sleep就可以嗎?)

謝謝各位!
編輯記錄
zhgwbzhd 重新編輯於 2008-08-20 23:37:13, 註解 無‧
zhgwbzhd 重新編輯於 2008-08-21 09:20:57, 註解 無‧
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-08-21 10:50:21 IP:210.208.xxx.xxx 訂閱
(1)先寫以下這樣子,看看可不可以

[code cpp]
Forms::Application->ProcessMessages();
[/code]

(2)在 ServiceExecute 裡面加 Sleep 是正確的,例如:

[code cpp]
void __fastcall TPaoService::ServiceExecute(TService *Sender)
{
while(!Terminated)
{
Sleep(10);
ServiceThread->ProcessRequests(false);
}
}
[/code]
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
careychen
尊榮會員


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-08-21 11:15:06 IP:218.210.xxx.xxx 訂閱
Hi, 使用 Indy TCP Server 基本上他不大會造成如此重的負擔,他的每一個連線,都是 Thread ,所以你的如此做法,等於是讓
每個連來的連線,都在跑 while ,看了你之前的相關的 po 文

關于使用IdTCPServer、ADOQUERY對SQL數據庫操作的疑問

你是為了能夠讓 Ado 的部份能夠穩定使用,其實小弟後來依 lu 大的方式改了之後,也比較穩定了,建議你可以這樣改看看
如此就不用 while 的方式,而且每個 ADO 都能夠穩定處理,我這邊試過每秒1000 次同時呼叫同一個指令,也沒事了
之後沒改 Lu 大的方法前,沒 200 次就掛了

抱歉,我用 Delphi 的,不知你能不能理解
[code delphi]
// Main Form
procedure TIdTCPServerExceute((AContext: TIdContext); // 我是 Indy 10
begin
// 呼叫 ADO Function
if dmDatabase.Login(AContext.ReadLn) then
AContext.WriteLN("Success Login")
else
AContext.WriteLN("Fail");
end;

// Database
function TdmDatabase.Login(Account: String): Boolean;
begin
CoInitialize(nil);

with sp_Login do
try
try
Close;
ConnectionString := ADOConnection.ConnectionString; // 每個元件使用自己的 Connection 不共用
Parameters.ParamByName('@iMemberID').Value := tsClientMessage.Values['MemberID'];
Open;.

if ....... then ...... Result := True;

except
Result := False;
end;
finally
Close;
end;

CoUninitialize;
end;
[/code]

小弟的方法也許也不是最好的,如果 Lu 大有看到本文的,也可以給小弟一點意見

------
價值的展現,來自於你用哪一個角度來看待它!!
編輯記錄
careychen 重新編輯於 2008-08-21 11:26:46, 註解 無‧
zhgwbzhd
一般會員


發表:10
回覆:32
積分:18
註冊:2008-07-24

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-08-21 12:05:07 IP:221.218.xxx.xxx 未訂閱
  1. 依小弟愚見,妳的方法是每一個鏈接有TdmDatabase.Login來創建一個ADO。
  2. 那假設同時數量鉅大的話,是不是ADO鏈接太多暸??
  3. // Main Form
  4. procedure TIdTCPServerExceute((AContext: TIdContext); // 我是 Indy 10
  5. begin
  6. // 呼叫 ADO Function
  7. if dmDatabase.Login(AContext.ReadLn) then
  8. AContext.WriteLN("Success Login")
  9. else
  10. AContext.WriteLN("Fail");
  11. end;
  12. // Database
  13. function TdmDatabase.Login(Account: String): Boolean;
  14. begin
  15. CoInitialize(nil);
  16. with sp_Login do //小弟不知這句是和含義。
  17. try
  18. try
  19. Close;
  20. ConnectionString := ADOConnection.ConnectionString; // 每個元件使用自己的 Connection 不共用
  21. Parameters.ParamByName('@iMemberID').Value := tsClientMessage.Values['MemberID'];
  22. Open;.
  23. if ....... then ...... Result := True;
  24. except
  25. Result := False;
  26. end;
  27. finally
  28. Close;
  29. end;
  30. CoUninitialize;
  31. end;
zhgwbzhd
一般會員


發表:10
回覆:32
積分:18
註冊:2008-07-24

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-08-21 12:18:54 IP:221.218.xxx.xxx 未訂閱
謝謝各位!

1、確實增加Forms::之后就沒問題了。不過不知道原因是什么。
2、在ServiceExecute 裡面加 Sleep 是可以的,不過把ServiceThread->ProcessRequests(true)也可。
由于幫助中說的較少,不知這兩種方法哪種更優?

===================引 用 RaynorPao 文 章===================
(1)先寫以下這樣子,看看可不可以

[code cpp]
Forms::Application->ProcessMessages();
[/code]

(2)在 ServiceExecute 裡面加 Sleep 是正確的,例如:

[code cpp]
void __fastcall TPaoService::ServiceExecute(TService *Sender)
{
while(!Terminated)
{
Sleep(10);
ServiceThread->ProcessRequests(false);
}
}
[/code]
careychen
尊榮會員


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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-08-21 12:49:52 IP:218.210.xxx.xxx 訂閱
其實小弟的淺見是覺得要看大大你想【怎麼處理事情】

你用佇列的方式來做,當然是減少 Connections ,但…你每個 Connection 必須一個一個處理後面一直堆上來的工作
那麼~~,你就必須【保證】您的 SQL 的回覆都能非常的好,不然,就會愈塞愈多哦,然後 Client 就必須等待了,
而且再來可以想到的,你的下一個問題會問~~~,那 ADO 的資料回覆,我該怎麼丟回 Client ,因為此時你是丟給佇列
去處理了,你當時的 Thread 也不再動作了,所以當佇列處理完成時,你就必須再丟回給 Request 的 Client ,而這個
佇列的動作,加入新的佇列、移出新的佇列,又是一個新的課題,如何才不會有兩個以上的函數同時存取,會不會一個刪
、一個加,造成記憶體錯誤,這些大大你可能都要考慮一下哦

小弟的方式,只是要求快速的 Response 給 Client ,所以當然是用很多的 Connection ,但小弟這邊能保證是每條
sql 處理都是相關快速,所以上面的例子是【處理完就 Disconnect 了】所以不大會有【數據量大時很多 Connection】
當然還是會有可能,但都是快速處理後,就 Disconnect;
------
價值的展現,來自於你用哪一個角度來看待它!!
zhgwbzhd
一般會員


發表:10
回覆:32
積分:18
註冊:2008-07-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-08-21 22:26:07 IP:221.218.xxx.xxx 未訂閱
OK,謝謝樓上的弟兄。

據說INDY的最大承載量為600.可能是說INDY9的版本,不知道INDY10的最大承載量是多少啊??

謝謝!
careychen
尊榮會員


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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-08-21 22:54:18 IP:59.126.xxx.xxx 訂閱
其實我的程式也許 loading 太輕,以前曾經跑到 1500 還 ok ,但 1700 時連 MainForm 都掛了
但那時是 Indy 9 ,現在新版的 indy 10 ,實際的還沒跑過,目前才 100 多,所以還不知承載狀況

===================引 用 zhgwbzhd 文 章===================
OK,謝謝樓上的弟兄。

據說INDY的最大承載量為600.可能是說INDY9的版本,不知道INDY10的最大承載量是多少啊??

謝謝!
------
價值的展現,來自於你用哪一個角度來看待它!!
zhgwbzhd
一般會員


發表:10
回覆:32
積分:18
註冊:2008-07-24

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-08-21 23:01:20 IP:221.218.xxx.xxx 未訂閱
其實要攷慮INDy的最大並髮數之外也要攷慮操作繫統的最大並髮數,如果採用windows作為服務器,也要脩改他的tcp最大鏈接數。
系統時間:2017-10-23 23:17:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!