回答
数据库查询阻塞了您的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. Npgsql冻结时执行查询
- 3. 在重建WPF UI时防止冻结?
- 4. 防止cmdlet冻结powershell
- 5. 防止表单冻结
- 6. 防止表单冻结
- 7. 如何防止我的JFrame冻结?
- 8. 如何防止短暂冻结视图
- 9. 如何防止可可粉冻结?
- 10. 如何防止使用QThread冻结GUI?
- 11. MySQL查询冻结
- 12. CFRunLoopRunInMode冻结主窗口
- 13. 调用窗体并冻结
- 14. Windows窗体冻结显示()
- 15. WPF/XAML:如何执行线程进程并防止主UI忙/冻结?
- 16. 如何停止冻结listView
- 17. iOS 5+ - 执行请求时冻结主线程执行
- 18. pthread_join()和冻结执行
- 19. 执行命令被冻结
- 20. 如何在使用HttpWebRequest时防止UI冻结?
- 21. 如何冻结程序的执行?
- 22. wpf - 窗口冻结
- 23. ctrl - ]冻结窗口?
- 24. SoapUI窗口冻结
- 25. Pyexcelerate冻结窗格
- 26. socket.connect()冻结窗口
- 27. 防止调用冻结形式的AddRange
- 28. 避免dequeueReusableCellWithIdentifier以防止UITableViewCell冻结
- 29. 防止服务器超载冻结 - linux
- 30. Pygame窗口冻结时代码运行
我不熟悉的设置IB组件集成到单独的线程。请 - 你可以提供一些例子吗? –
杀死好榜样!非常感谢Heinrich Ulbricht。 –
还有一个问题 - 我可以自由地将数据集附加到某个表中,或者在数据可视化之前我会做其他事情吗? –