詹姆斯 L 可能已经成功了。由于 Indy 线程没有消息循环,因此您必须依赖另一种机制 - 例如只读线程本地属性(例如他的示例中的UserCount和/或LastSem ) - 并使用服务器的主线程来运行 TTimer在给定一些规则的情况下解放资源。
编辑:另一个想法是创建一个通用数据结构(下面的示例),每次线程完成其工作时都会更新它。
警告:仅凭头脑编码...它可能无法编译... ;-)
例子:
TThreadStatus = (tsDoingMyJob, tsFinished);
TThreadStatusInfo = class
private
fTStatus : TThreadStatus;
fDTFinished : TDateTime;
procedure SetThreadStatus(value: TThreadStatus);
public
property ThreadStatus: TThreadStatus read fTStatus write SetStatus;
property FinishedTime: TDateTime read fDTFinished;
procedure FinishJob ;
procedure DoJob;
end
procedure TThreadStatusInfo.SetThreadStatus(value : TThreadStatus)
begin
fTStatus = value;
case fTStatus of
tsDoingMyJob :
fDTFinished = TDateTime(0);
tsFinished:
fDTFinished = Now;
end;
end;
procedure TThreadStatusInfo.FinishJob;
begin
ThreadStatus := tsFinished;
end;
procedure TThreadStatusInfo.DoJob;
begin
ThreadStatus := tsDoingMyJob;
end;
将它放入一个列表(您喜欢的任何列表类)中,并确保每个线程都与该列表中的索引相关联。仅当您不再使用该数量的线程时才从列表中删除项目(缩小列表)。当你创建一个新线程时添加一个项目(例如,你有 4 个线程,现在你需要第 5 个,你在主线程上创建一个新项目)。
由于每个线程在列表中都有一个索引,因此您不需要封装此写入(对 T 上的调用 TCriticalSection.
您可以毫无困难地阅读此列表,在主线程上使用 TTimer 来检查每个线程的状态。由于您有每个线程的完成时间,因此您可以计算超时。