2013-04-24 107 views
0

我必須處理一個非常長的數據庫表,並考慮中止此循環的最常用方法。主要的代碼序列是這樣的中止數據庫表的長時間運行過程:想法?

procedure TForm.ProcessmyTable(Sender : TObject); 
begin 
..... 

myTable.first; 

repeat 
    ReadSingleRecordfromTable (MyTable, aRecord) ; 
    ProcessMyRecord(aRecord) ; 
    MyTable.next; 
until MYTable.EOF; 

end; 


unit .... ; 

procedure ProcessMyRecord(aRecord : TMyDataRecord) ; 
begin 

    // do not have user interface stuff here 
    // Application.Processmessages will not work here !!! 


    .... (long running code sequence) 

end; 

可以做一個計時器,打破基於使用var作爲標誌的支持定時循環....但是這真的是解決這一問題的最聰明的方式?

回答

0

什麼時候你想中止?如果用戶說'停止'需要很長時間?

在這兩種情況下,改變你的

until MYTable.EOF; 

until MYTable.EOF or Aborted; 

然後設置中止布爾值,當定時器觸發時,或者當用戶按下一個鍵(請注意,你就必須使用應用程序.ProcessMessages循環中的程序能夠處理按鍵)。這不會中止您的處理程序,但每個記錄後。如果速度不夠快,你將不得不顯示你的記錄處理程序。

+0

你需要Application.ProcessMessages在任何情況下。計時器需要處理WM_TIMER消息。 – kobik 2013-04-24 09:40:54

+0

如果他想在迭代之間切換 - 那麼他不需要計時器,只需要一個'GetTickCount' – 2013-04-24 13:43:13

1

如果此代碼在主線程中運行,那麼如果您希望用戶與您的程序進行交互並中止,則需要服務消息隊列(即調用Application.ProcessMessages)。在這種情況下,我認爲你已經知道解決方案。致電Application.ProcessMessages。如果用戶選擇中止,則設置一個布爾標誌並在最內循環中定期檢查該標誌。

當然,這一切都相當混亂。根本的問題是你正在GUI線程上執行長時間運行的操作。這是你不應該做的事情。將數據庫處理代碼移到另一個線程上。如果用戶選擇中止,則通知該線程它將中止。例如,調用線程的Terminate方法將是實現此目的的一種方法。

0

如果用戶可能想要在Windows應用程序中肯定放棄這麼長的過程,那麼應該與GUI進行一些交互,完成記錄的計數或進度條(如果不是每個記錄上都有)定期更新標籤或進度條的任何調用都將提供設置中止標誌的機會(因此不需要過程消息)。此外,如果用戶可以看到一些進展,他們可能不太可能在無聊時中止,但95%完成。

恕我直言:)