Ошибки управления потоками в Delphi XE7 для Android: причины и решения
Вопрос пользователя касается проблемы, возникающей при работе с потоками в Delphi XE7 на Android-платформе. Проблема заключается в том, что при создании объектов класса TSubThread происходит ошибка примерно после 1,8-2 миллионов запусков программы. При этом та же программа работает корректно на Windows и iOS.
Код класса TSubThread
TSubThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
procedure TSubThread.Execute;
begin
// здесь ничего не делаем
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 FGetCounterOK;
property CountErr: Int64 read FGetCounterErr;
constructor Create;
destructor Destroy; override;
end;
function TMainThread.FGetCounterOK: Int64;
begin
Result := TInterlocked.Read(FCounterOK);
end;
function TMainThread.FGetCounterErr: Int64;
begin
Result := TInterlocked.Read(FCounterErr);
end;
procedure TMainThread.Execute;
const
CSTMaxThreads = 20;
var
i: Integer;
los: TArray<TSubThread>;
begin
try
while not Terminated do
begin
// Создание экземпляра TSubThread и добавление в динамический массив
while Length(los) < CSTMaxThreads do
begin
try
l := TSubThread.Create;
los := los + [l];
l.Start;
TInterlocked.Increment(FCounterOK);
except
on E: System.SysUtils.Exception do
TInterlocked.Increment(FCounterErr);
end;
end;
// Освобождение завершенных потоков
for i := Length(los) - 1 downto 0 do
begin
if los[i].Finished then
begin
los[i].DisposeOf;
los[i] := nil;
Delete(los, i, 1);
end;
end;
end;
finally
// Освобождение всех потоков при завершении главного потока
for i := Length(los) - 1 downto 0 do
begin
los[i].DisposeOf;
los[i] := nil;
end;
SetLength(los, 0);
end;
end;
Описание проблемы
Пользователь столкнулся с ошибкой при создании объектов класса TSubThread на Android-платформе после примерно 1,8-2 миллионов запусков программы. Ошибка имеет сообщение "Create error: Try again", и программа работает без ошибок на Windows и iOS.
Альтернативный ответ
В альтернативном ответе пользователь предлагает заменить динамический массив потоков на переменную, отвечающую за поток, и предполагает, что это может решить проблему.
Подтвержденный ответ
Подтвержденный ответ указывает на вероятную причину проблемы: слишком большое количество создаваемых потоков и исчерпание ресурсов системы для их поддержки. Предлагается установить свойство FreeOnTerminate в True, что может помочь избежать подобных проблем.
Комментарии
В комментариях обсуждаются различные способы решения проблемы, включая установку FreeOnTerminate в True и использование пула потоков с внутренним переиспользованием.
Решение проблемы
Для решения проблемы можно использовать несколько подходов:
Установить свойство FreeOnTerminate в True для каждого создаваемого потока. Это позволит системе автоматически освободить ресурсы потока после его завершения.
constructor TSubThread.Create;
begin
inherited Create(True);
FreeOnTerminate := True;
end;
Заменить динамический массив потоков на переменную, которая будет хранить один поток, и переиспользовать этот поток после его завершения.
var
CurrentThread: TSubThread;
begin
CurrentThread := TSubThread.Create;
CurrentThread.Start;
// Ждать завершения потока
CurrentThread.WaitFor;
// Переиспользовать поток
CurrentThread.FreeOnTerminate := False;
// Ваши операции с потоком
CurrentThread.Start;
// Повторно ждать завершения потока перед переиспользованием
CurrentThread.WaitFor;
end;
Использовать пул потоков, который будет управлять созданием и уничтожением потоков, а также их переиспользованием.
Применение этих методов может помочь избежать исчерпания ресурсов и улучшить общую производительность и стабильность приложения на Android-платформе.
Описание контекста: Пользователь сталкивается с ошибкой при работе с потоками в Delphi XE7 на Android, которая проявляется после многократного создания объектов класса `TSubThread` и предполагается связана с исчерпанием ресурсов системы.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.