我有一个数据库应用程序异步获取db记录集,非常类似于Threaded Delphi ADO Query
每次用户点击刷新时,都会创建一个新的foreach($xml as $item){
$sku = $item->code;
$x_img = $xml->xpath("//file[type='images_800x600' and ./code='$sku']/url");
// I also tried
$x_img = $xml->xpath("//file[type='images_800x600' and ./code='$sku']/following-sibling::url");
var_dump($x_img);
}
来获取记录集。
当发生这种情况时,我想丢弃所有先前的请求并仅处理最后一个请求。
所以我创建了一个名为TDBThread
的类字段,每次发出请求时都会递增。我不会尝试取消/中止以前的请求,也不会继续引用创建的线程。
FRequestID
在终止时,我检查线程procedure TForm1.RefreshClick(Sender: TObject);
var
T: TDBThread;
begin
Inc(FRequestID);
T := TDBThread.Create(True); // Suspended
T.FreeOnTerminate := True;
T.RequestID := FRequestID;
T.SQL := 'select * from mytable where ...';
T.OnTerminate := DBThreadTerminate;
T.Resume;
end;
是否是最后一个RequestID
,然后才处理请求。
FRequestID
我的问题是这种方法是否正确(和线程安全)并且是否有更好的方法来处理最后一个请求?
注意:我在使用Delphi 7。
答案 0 :(得分:0)
您的代码是线程安全的,并且在您定义的内容中是正确的(我不指望您为该请求ID溢出整数限制)。您似乎意识到您将无法终止您没有引用的线程并且您正在浪费资源。值得补充的是,您无法取消正在运行的DBMS操作,因为您链接的代码实现了同步提取,只是在工作线程内执行而ADO无法取消这些操作。
有一种更好的方法可以做到这一点。你可以,例如只创建一个线程(因为为每个任务创建一个线程对于频繁的任务来说是低效的),有一组命令(队列或列表),让线程睡眠等待系统事件发出信号的工作
或者代替命令集合每个命令一个这样的线程(但在这里你应该考虑应用程序中使用的命令数量)。
您可以实现异步ADO执行(可以取消,因此您可以中断运行操作并执行另一个)。