Delphi 2010 - Wininet не хватает ручек
У меня есть приложение, которое интенсивно использует Wininet
функции, чтобы получить некоторые данные из Интернета. Иногда я получаю очень странные сообщения об ошибках, связанных с дескриптором:
Internal error in ConnectToHost when trying to create a session
ERROR_INTERNET_OUT_OF_HANDLES: No more handles could be generated at this time. Wininet error code = 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;
Запустив этот пример на моем профилировщике, я получаю те же проблемы, связанные с этим
я думаю что InternetCloseHandle
не освобождает дескриптор, как должно быть, потому что мой профиль ресурса говорит мне, что у меня есть 3 живых дескриптора, когда я закрываю приложение. Это ручки, которые не освобождаются:
pRequest
pConnection
pSession
Кто-нибудь знает, как от этого избавиться?
РЕДАКТИРОВАТЬ
Функция InternetCloseHandle
работает нормально, возвращаемое значение true
,
РЕДАКТИРОВАТЬ
Я много искал в Интернете, но я не смог найти никого, кто бы жаловался на это. Но это происходит. Я хотел бы знать, воспроизводил ли кто-нибудь проблему или это только я.
2 ответа
Это оказалось проблемой AQtime. Я скачал другой профилировщик, и я также взглянул на диспетчер задач, и кажется, что дескрипторы выпускаются. Но я все еще получаю no more handles
иногда ошибка, и я понятия не имею, почему. Но я открою другой вопрос, так как этот был просто для того, чтобы увидеть, почему эти ручки не были выпущены.
Спасибо за всю помощь, которую я получил.
Протокол Http имеет некоторые ограничения, и Wininet использует их. Проверьте в WinInet лимиты соединений на сервер:
WinInet ограничивает подключения к одному серверу HTTP 1.0 четырьмя одновременными подключениями. Соединения с одним сервером HTTP 1.1 ограничены двумя одновременными соединениями. Спецификация HTTP 1.1 (RFC2616) предписывает ограничение двух соединений. Ограничение на четыре соединения для HTTP 1.0 является обязательным ограничением, которое совпадает со стандартом, который используется рядом популярных веб-браузеров.
Возможно, вам следует подождать, пока соединения не будут закрыты, прежде чем пытаться установить новое соединение.