gpt4 book ai didi

multithreading - 仅处理最后一个TThread任务并丢弃先前的线程

转载 作者:行者123 更新时间:2023-12-03 18:44:49 25 4
gpt4 key购买 nike

我有一个数据库应用程序,它非常类似于Threaded Delphi ADO Query,异步地获取数据库记录集。

每次用户单击刷新都会创建一个新的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,然后才处理请求。
procedure TForm1.DBThreadTerminate(Sender: TObject);
var
T: TDBThread;
begin
T := TDBThread(Sender);
if FRequestID = T.RequestID then
begin
Memo1.Lines.Add('*** Thread terminated ok ' + IntToStr(T.RequestID));
MainDS.RecordSet := T.RecordSet;
end
else
Memo1.Lines.Add('Thread discarded: ' + IntToStr(T.RequestID ));
end;

我的问题是这种方法正确(并且线程安全),并且是否有更好的方法仅处理最后一个请求?

注意:我正在使用Delphi 7。

最佳答案

您的代码是线程安全的,并且在定义的意义上是正确的(我不认为您对该请求ID溢出整数限制)。似乎您知道您将无法终止您没有引用的线程,并且您正在浪费资源。值得补充的是,您将无法取消正在运行的DBMS操作,因为链接的代码实现了同步提取,仅在工作线程中执行,而ADO无法取消这些操作。

不过,有更好的方法可以做到这一点。您可以例如仅创建一个线程(因为每个任务创建一个线程对于频繁执行的任务而言效率低下),具有命令(队列或列表)的集合,并让线程休眠以等待系统事件指示的工作。

或者,也可以代替每个命令一个这样的线程来收集命令(但是在这里,您应该考虑一下应用程序中使用的命令数量)。

而且,您可以实现异步ADO执行(可以将其取消,因此您将中断正在运行的操作并执行另一个操作)。

关于multithreading - 仅处理最后一个TThread任务并丢弃先前的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46130011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com