【发布时间】:2017-09-09 11:08:36
【问题描述】:
我有一个数据库应用程序,它异步获取数据库记录集,非常类似于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。
【问题讨论】:
-
我会以不同的方式处理这个问题。当线程正在执行它的工作时禁用刷新按钮。那么就不需要多个线程,不需要任何可能不是线程安全访问的整数。也许将 TAction 链接到按钮,如果 DBThread 正在运行,请使用 OnUpdate 事件将其禁用。
-
@Nil,谢谢,不管是点击按钮还是附加
TAction。您不能拒绝用户在 DBThread 运行时点击刷新或执行新查询(例如使用新的搜索条件)。至少不在我的程序中。 -
我认为你需要实现其中的一些stackoverflow.com/questions/4044855/…
标签: multithreading delphi delphi-7