Вопрос, который возник у разработчика, заключается в некорректной работе с TThreadList в Delphi. Несмотря на то, что код, представленный автором, должен был корректно добавлять элементы в список клиентов, ожидаемый результат (6 клиентов и первый хост HOST1) не был достигнут. Вместо этого, был получен результат в виде 1 клиента со пустым полем хоста.
Проблема
В коде присутствует ошибка в логике добавления клиентов в TThreadList. Создается объект Client, но при добавлении в список используется не List, а сам объект Clients, что приводит к вызову метода Add напрямую на TThreadList, а не на блокированном списке.
Решение
В соответствии с подтвержденным ответом, для корректной работы с TThreadList необходимо использовать блокированный список (LockList) для добавления элементов. Также важно отметить, что по умолчанию TThreadList настроен на игнорирование дубликатов (dupIgnore), что может привести к ошибкам. В данном случае, необходимо установить параметр Duplicates в dupAccept.
Кроме того, важно понимать, что после вызова Free для объекта Client, его память может быть освобождена и переиспользована, что приводит к потере данных. Следовательно, при попытке обратиться к объекту после его уничтожения, вы получите пустые значения.
Пример корректного кода
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
type
TClient = class(TObject)
Host: String;
end;
const
Hosts: Array[0..5] of String = ('HOST1', 'HOST2', 'HOST3', 'HOST4', 'HOST5', 'HOST6');
var
I: Integer;
List: TList;
Client: TClient;
Clients: TThreadList;
begin
Clients := TThreadList.Create;
Clients.Duplicates := dupAccept;
for I := Low(Hosts) to High(Hosts) do
begin
Client := TClient.Create;
Client.Host := Hosts[I];
List := Clients.LockList;
try
List.Add(Client);
finally
Clients.UnlockList;
end;
end;
List := Clients.LockList;
try
Writeln(List.Count);
Writeln(TClient(List.Items[0]).Host);
finally
Clients.UnlockList;
end;
end.
В этом примере кода сначала создается экземпляр TThreadList, устанавливается параметр Duplicates в dupAccept, затем в цикле создаются объекты TClient, инициализируются их свойства, блокируется список и корректно добавляются объекты в список.
Современные подходы
В современном программировании на Delphi рекомендуется использовать обобщенные коллекции, которые предоставляют более безопасный и удобный интерфейс. Пример использования TThreadList с обобщениями:
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Generics.Collections;
type
TClient = class
Host: string;
constructor Create(AHost: string);
end;
constructor TClient.Create(AHost: string);
begin
inherited Create;
Host := AHost;
end;
const
Hosts: array[0..5] of string = ('HOST1', 'HOST2', 'HOST3', 'HOST4', 'HOST5', 'HOST6');
var
List: TList<TClient>;
Clients: TThreadList<TClient>;
begin
Clients := TThreadList<TClient>.Create;
Clients.Duplicates := dupAccept;
for Host in Hosts do
Clients.Add(TClient.Create(Host));
List := Clients.LockList;
try
Writeln(List.Count);
Writeln(List.First.Host);
finally
Clients.UnlockList;
end;
end.
Использование обобщений позволяет избежать многих ошибок и упрощает поддержку кода.
Разработчик столкнулся с проблемой некорректного добавления элементов в `TThreadList` в Delphi из-за ошибки в логике кода.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.