2011-02-16 99 views
0

我在C++ Builder中XE OnExecute下面的代碼:印OnExecute首先閱讀慢

void __fastcall Test::TestExecute(TIdContext* AContext) 
{ 
    try 
    { 
     // get the command directive 
     DWORD startTime = timeGetTime(); 
     UnicodeString DBCommand = AContext->Connection->IOHandler->ReadChar(); 
     DWORD endTime = timeGetTime(); 
     UnicodeString log; 
     log.printf(L"getting command %d ms", endTime - startTime); 
     Log(log); 
     ... 

日誌開始在得到命令100毫秒,偷偷到300那裏停留了應用程序運行的剩餘。我認爲OnExecute一旦數據在緩衝區中被調用,那麼爲什麼第一次讀取要成功需要100到300毫秒?

在第一次讀取相同的OnExecute之後,所有其他數據被非常快速地讀取(毫秒到亞毫秒)。

可能會出現什麼問題?

編輯:

在法的推出:AContext->Connection->IOHandler->InputBuffer->Size爲0。第一次讀返回後AContext->Connection->IOHandler->InputBuffer->Size包含詮釋他的讀緩存後留下什麼。所以這意味着OnExecute在調用者實際可用的任何數據之前被調用。所以100-300毫秒是指在Indy從套接字中獲取數據並將其放入緩衝區後,它收到數據到達的通知。這似乎太長了。

編輯:

刪除do{因爲它意味着一個循環,是不存在。

回答

0

OnExecute事件根本不依賴於套接字緩衝區。 TIdTCPServer開始在調用OnConnect事件後立即呼叫OnExecute,並且在無限循環中繼續呼叫OnExecute,直到客戶端斷開連接(換句話說,您不應該在自己的OnExecute處理程序中循環讀取數據包,處理,退出,等待爲下一個事件,重複)。

你是正確的InputBuffer可以增加比你要求的代碼大。所有IOHandler的讀取方法僅從InputBuffer獲取其數據,而不是直接從套接字獲取數據。如果InputBuffer沒有足夠的字節高速緩存以滿足讀取請求,IOHandler將等待字節在套接字上可用,然後將所有字節讀入InputBuffer以供以後使用。這最大限度地減少了套接字需要被訪問的頻率,並有助於保持套接字對新數據的響應。

+0

對不起,`do {`暗示着一個不存在的循環。我不會在`OnExecute`循環,我使用`do {} while(false);`提前退出。數據到達時調用OnExecute,是否正確?但在調用「OnExecute」之後,仍需要100到300 ms才能獲得第一個數據。我不記得這發生在C++ Builder 2010中。 – 2011-02-16 14:05:14