我正在使用 Delphi XE6 和 UniDAC 以及 MySQL
我的 DM 中有一些 TUniQuery 组件,我想重复刷新主题,所以我在主窗体中放置了一些计时器,在每个计时器中我创建一个线程并向其传递一个查询以刷新数据:
例如:
TUpdateThread = class(TThread)
private
FQuery : TUniQuery;
FResultHandle : THandle;
public
constructor Create(var Query : TUniQuery; ResultHandle : THandle);
protected
procedure Execute; override;
end;
constructor TUpdateThread.Create(var Query: TUniQuery; ResultHandle : THandle);
begin
inherited Create;
Suspend;
FQuery := Query;
FResultHandle := ResultHandle;
FreeOnTerminate := True;
Resume;
end;
procedure TUpdateThread.Execute;
var
Msg : String;
B : Boolean;
begin
try
B := True;
try
FQuery.Refresh;
except
on E:Exception do
begin
B := False;
Msg := 'Error : ' + #13 + E.Message;
SendMessage(FResultHandle, MSG_UPDATERESULT, 2, Integer(Msg));
end;
end;
finally
if B = True then
SendMessage(FResultHandle, MSG_UPDATERESULT, 1, 1);
Terminate;
end;
end;
有时它会成功完成,但很多时候我会遇到一些错误,例如 AV 或“Net Pack Header ...”错误 或者有时我的网格(Ehlib DBGrid)出现问题,例如绘制行时出错或...(特别是当我使用DisableControls和EnableControls时) 所有查询都有相同的连接,我认为每个线程应该有自己的连接,因为所有计时器间隔都是相同的,我建议有时刷新查询会互相中断
事实上,我的数据库位于VPS服务器中,并且有一些客户端应用程序,我想在客户端中拥有Live-Tables并重复更新主题
实现这一目标的最佳方法是什么? 我应该如何更新我的表而不应用程序挂起! 有一些组件如 TThreadTimer (或...),主题对这种情况有用吗?!
谢谢...
最佳答案
第一期在这里:
constructor TUpdateThread.Create(var Query: TUniQuery; ResultHandle : THandle);
begin
inherited Create; // Create with no arguments
Suspend; // means CreateSuspended = false
FQuery := Query;
FResultHandle := ResultHandle;
FreeOnTerminate := True;
Resume;
end;
在这里,您使用默认构造函数 (CreateSuspished = false
) 创建线程,线程会立即开始运行。您立即调用挂起
(已弃用,不应使用),但这仍然是一个竞争条件,因为您的线程可能会也可能不会在之前开始尝试刷新
您的查询你已经分配了它。要创建处于挂起状态的线程,请使用重载构造函数
inherited Create(true);
Resume
也已弃用。相反,您应该使用 Start;
。
此外,您还将 TUniQuery
传递给该线程的构造函数。我想,我们可以假设这个查询与主线程有亲和性 - 这就是说它(可能)是表单上的可视组件,具有与可视组件的数据绑定(bind),或者以其他方式与用户或用户进行交互界面。
如果是这样,答案是您根本无法执行此操作 - 线程无法修改与另一个线程具有关联性的对象。例如,当后台线程同时销毁记录以准备刷新查询内容时,您的界面可能正在从查询中检索记录。自然这会引起各种各样的问题。
简单的解决方案是使用常规计时器并在主线程上同步刷新。如果这需要太长时间,那么您需要考虑完全不同的策略。我们确实没有足够的信息来提出更多建议。如果网络访问和 I/O 是瓶颈,那么您可能会考虑异步刷新到线程拥有的单独查询对象,然后将其同步分配给您的 View 组件。
关于mysql - 刷新线程中的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32715717/