mysql - 刷新线程中的查询

标签 mysql multithreading performance delphi unidac

我正在使用 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/

相关文章:

php - 从表格收集的数据不完整

c# - 多线程应用调试问题

java - 如何调度 Java 线程

python - 根据每个像素的位置有效地应用函数

java - 使用一个 3d 阵列还是两个 2d 阵列更好?

algorithm - Sieve of Eratosthenes 算法的时间复杂度

MYSQL用户定义变量问题

mysql - 从 2 个表中选择查询

mysql - 如果用户在连接到 MySQL 时被删除,会发生什么情况?

java - JVMTI_ERROR_THREAD_NOT_ALIVE 错误使用多个 Activity 和 OpenWeatherMap API