【发布时间】:2026-01-12 19:00:01
【问题描述】:
提前感谢您的宝贵时间。
先发简单的代码。
TSubThread 代码
TSubThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
procedure TSubThread.Execute;
begin
// do nothing
end;
constructor TSubThread.Create;
begin
inherited Create(True);
Self.FreeOnTerminate:= False;
end;
TMainThread的代码
TMainThread = class(TThread)
private
FCounterOK,
FCounterErr:int64;
function FGetCounterOK:Int64;
function FGetCounterErr:Int64;
protected
procedure Execute; override;
public
property CountOK:Int64 read FGetCounter;
property CountErr:Int64 read FGetCounterErr;
constructor Create;
destructor Destroy; override;
end;
function TMainThread.FGetCounterOK:Int64;
begin
result:= TInterlocked.Read(Self.FCounterOK);
end;
function TMainThread.FGetCounterErr:Int64;
begin
result:= TInterlocked.Read(Self.FCounterErr);
end;
procedure TMainThread.Execute;
const
CSTMaxThreads = 20;
var
i: Integer;
los:TArray<TSubThread>;
begin
try
while not Self.Terminated do
begin
//Create instance of TSubThread and append to DynArray
while Length(los) < CSTMaxThreads do
begin
try
l:= TSubThread.Create;
los:= los + [l];
l.Start;
TInterLocked.Increment(Self.FCounterOK);
except on E:System.SysUtils.Exception do
TInterLocked.Increment(Self.FCounterErr);
end;
end;
for i:= Length(los)-1 downto 0 do
begin
// Free thread Object
if los[i].Finished then
begin
los[i].DisposeOf;
los[i]:= nil;
Delete(los,i,1);
end;
end;
end;
finally
// MainThread Terminated, Free all.
for i := Length(los)-1 downto 0 do
begin
los[i].DisposeOf;
los[i]:= nil;
end;
delete(los,0,Length(los));
end;
end;
使用 E.ToString = "Create error: Try again." 在 Android 平台上运行大约 1800000 ~ 2000000 次(通过 CounterOK 和 CounterErr 属性)后创建 TSubThread 引发异常...并且相同的程序在 Windows 上运行完美和IOS。 代码有问题吗?
【问题讨论】:
-
我不明白你为什么打电话给
DisposeOf()。当引用计数达到零时,只需将对象设置为 nil 就会将对象从堆中丢弃。变量l未声明,我假设它是Execute方法的本地变量。在线程创建while循环后尝试将其设置为nil,只是为了摆脱最后创建的子线程的额外引用计数。 -
TThread 对 ARC 非常挑剔,因此您必须非常小心。自首次添加 ARC 以来,TThread 在每个版本中都受到 ARC 问题的困扰。
-
@LU RD DisposeOf() 是从 System.Classes 中的方法 ThreadProc() 复制而来的。当 thread.FreeOnTerminate=true 时,ThreadProc() 将调用 Thread.DisposeOf 并且不会发生任何问题。
-
用线程变量替换动态线程数组可以避免这个问题。我的动态数组操作有问题吗?
标签: android multithreading delphi dynamic-arrays