回答
數據庫查詢阻塞了您的UI線程。爲您的查詢使用後臺線程。一個類似的話題已經涵蓋了here和here。
你要求一個例子,所以這裏是一個例子。請注意,代碼是僞代碼,因爲它與普通的TQuery
一起工作,跳過所有設置,拆除,錯誤檢查並直接包含在主窗體的單元中。它只是說明解決問題的一種方法。
// Create a descendant of TThread. This thread will execute your query
// asynchronously.
TMyQueryThread = class(TThread)
private
FQueryString: string;
FMyQuery: TQuery;
protected
procedure Execute; override;
public
constructor Create(QueryString: string);
destructor Destroy; override;
property MyQuery: TQuery read FMyQuery;
end;
// This processes the query result. Do whatever you need to do with the data,
// but remember to do it quick. Otherwise you will freeze your UI again.
procedure ProcessResult(Data: TDataSet);
begin
// process the data
while not Data.Eof do
Data.Next;
end;
// This will be called when the thread terminates.
//
// Context: The code in here is executed in the main thread.
procedure TForm1.HandleThreadTerminate(Sender: TObject);
var
SourceThread: TMyQueryThread;
begin
SourceThread:= TMyQueryThread(Sender);
// invoke data processing
ProcessResult(SourceThread.MyQuery);
end;
// When the user decides to run the query we create our thread. This call
// will take minimal time, so it doesn't block the UI.
//
// Context: The code in here is executed in the main thread.
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyQueryThread.Create('SELECT * FROM Table') do
begin
// we want to know when the thread finished its work so register for the event
OnTerminate := HandleThreadTerminate;
// this will free the thread object after OnTerminate has been called
FreeOnTerminate := True;
end;
end;
{ TMyQueryThread }
// Constructor of the thread class. This takes the sql string to be executed.
//
// Context: In this example, the code in here is executed in the main thread.
constructor TMyQueryThread.Create(QueryString: string);
begin
// don't forget to call inherited constructor; tell it to start running immediately
inherited Create(False);
// save query string
FQueryString := QueryString;
end;
// Do the work which used to freeze your UI.
//
// Context: The code in here does NOT run in the main thread.
procedure TMyQueryThread.Execute;
begin
// mock query - this is your TIBQuery
FMyQuery:= TQuery.Create(nil);
with FMyQuery do
begin
SQL.Text:= FQueryString;
// this will take a while but it doesn't matter because it only blocks the current thread, not the main thread
Open;
end;
end;
destructor TMyQueryThread.Destroy;
begin
FMyQuery.Free;
inherited;
end;
這適用於我使用的數據庫組件。請注意不要在Execute
中進行與UI相關的任何活動。代碼在主線程和查詢線程之間共享一個TQuery
。您不僅可以在線程內部創建查詢,還可以在數據庫連接中創建查詢。您應該爲每個從您查詢數據庫的每個線程使用一個連接。
您必須在後臺線程中執行您的查詢。國際海事組織更好的免費(與源)解決方案是組件TBMDThread(谷歌它)。我建議使用單獨的連接進行後臺查詢。
TBMDThread http://www.mitov.com/free_downloads
請解釋一下 - 「使用單獨連接」下的含義是什麼? –
Pre v2.5客戶端庫不是線程安全的。這意味着您必須使用隔離連接進行後臺查詢。 – rstrelba
但如何創建這樣的背景查詢? –
- 1. Webclient DownloadString凍結主窗體
- 2. 在重建WPF UI時防止凍結?
- 3. 防止表單凍結
- 4. 防止表單凍結
- 5. 防止cmdlet凍結powershell
- 6. 如何防止使用QThread凍結GUI?
- 7. 如何防止短暫凍結視圖
- 8. 如何防止可可粉凍結?
- 9. MySQL查詢凍結
- 10. CFRunLoopRunInMode凍結主窗口
- 11. Windows窗體凍結顯示()
- 12. 調用窗體並凍結
- 13. WPF/XAML:如何執行線程進程並防止主UI忙/凍結?
- 14. 如何停止凍結listView
- 15. pthread_join()和凍結執行
- 16. iOS 5+ - 執行請求時凍結主線程執行
- 17. 如何凍結程序的執行?
- 18. Pyexcelerate凍結窗格
- 19. ctrl - ]凍結窗口?
- 20. HttpURLConnection.getResponseCode()凍結執行/不超時
- 21. 代碼執行時加載gif「凍結」
- 22. 窗口正在凍結
- 23. Task.Run阻止主線程(凍結的UI)
- 24. MFC對話框窗體凍結
- 25. 贏窗體應用程序凍結
- 26. 調用凍結我的Windows窗體
- 27. 調試Windows窗體線程凍結
- 28. 運行SQL時dbext凍結
- 29. 在執行過程中Excel凍結
- 30. Javascript:防止瀏覽器在調用服務器時被凍結
我不熟悉的設置IB組件集成到單獨的線程。請 - 你可以提供一些例子嗎? –
殺死好榜樣!非常感謝Heinrich Ulbricht。 –
還有一個問題 - 我可以自由地將數據集附加到某個表中,或者在數據可視化之前我會做其他事情嗎? –