Устранение ошибки ERROR_INTERNET_OUT_OF_HANDLES при использовании Wininet в Delphi 2010
Введение
При работе с библиотекой Wininet в среде разработки Delphi 2010 пользователи могут столкнуться с ошибкой ERROR_INTERNET_OUT_OF_HANDLES, которая указывает на исчерпание количества доступных дескрипторов. Это может произойти, если приложение интенсивно использует функции Wininet для получения данных из интернета, и в результате создается большое количество дескрипторов, которые не освобождаются должным образом.
Описание проблемы
Пользователь столкнулся с проблемой, когда его приложение, активно использующее функции Wininet, иногда выдавало сообщения об ошибках, связанных с дескрипторами:
Внутренняя ошибка при подключении к хосту при попытке создания сессии
ERROR_INTERNET_OUT_OF_HANDLES: В данный момент не может быть сгенерировано больше дескрипторов. Код ошибки Wininet = 12001;
При возникновении ошибки было замечено, что приложение имело более 5000 созданных дескрипторов. Проблема была воспроизведена в простом приложении, которое не делало ничего, кроме создания и освобождения дескрипторов Wininet. После закрытия приложения оставались неосвобожденными дескрипторы сессии, подключения и запроса.
Анализ кода
Пример кода, представленный пользователем, демонстрирует создание и закрытие дескрипторов с использованием функций Wininet:
procedure Request(const AUrl: AnsiString);
var
sMethod: AnsiString;
pSession: HINTERNET;
pConnection: HINTERNET;
pRequest: HINTERNET;
port: Integer;
flags: DWord;
begin
pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(pSession) then
try
port := INTERNET_DEFAULT_HTTP_PORT;
pConnection := InternetConnectA(pSession, PAnsiChar(AUrl), port, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
if Assigned(pConnection) then
try
sMethod := 'GET';
flags := INTERNET_SERVICE_HTTP;
pRequest := HTTPOpenRequestA(pConnection, PAnsiChar(sMethod), PAnsiChar(AUrl), nil, nil, nil, flags, 0);
try
if Assigned(pRequest) then
ShowMessage('ok');
finally
InternetCloseHandle(pRequest);
end;
finally
InternetCloseHandle(pConnection);
end;
finally
InternetCloseHandle(pSession);
end;
end;
Подтвержденный ответ
Исходная проблема заключалась в использовании профайлера AQTime, который ошибочно указывал на проблемы с освобождением дескрипторов. После проверки другим профайлером и Task Manager, выяснилось, что освобождение дескрипторов происходит корректно.
Альтернативный ответ
Пользователь также рассматривал возможность использования компонента TIdHTTP из Indy, который также использует API Wininet, но в его случае не сталкивался с подобными проблемами.
Рекомендации
Избегайте частых открытий и закрытий дескрипторов при большом количестве запросов.
Рассмотрите возможность использования компонентов, таких как TIdHTTP, которые могут обрабатывать дескрипторы более эффективно.
При работе в многопоточной среде тщательно продумайте процесс обработки запросов, чтобы избежать проблем с дескрипторами.
Заключение
Ошибка ERROR_INTERNET_OUT_OF_HANDLES может быть вызвана неправильной работой профайлера или неправильным подходом к управлению дескрипторами. Важно тщательно анализировать код и использовать инструменты, которые корректно отображают состояние системы. В данном случае проблема была решена путем переключения на другой профайлер и подтверждена корректной работой освобождения дескрипторов.
Описание: При работе с библиотекой Wininet в Delphi 2010 возникла проблема с исчерпанием количества доступных дескрипторов, что привело к ошибке `ERROR_INTERNET_OUT_OF_HANDLES`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.