#delphi #asynchronous
Вопрос:
Как использовать асинхронный TNetHTTPClient? Я попытался выполнить следующий код, но он показывает ошибку.
procedure TForm1.Button1Click(Sender: TObject);
var
httpclient: TNetHTTPClient;
output: string;
begin
httpclient := TNetHTTPClient.Create(nil);
try
httpclient.Asynchronous := True;
output := httpclient.Get('https://google.com').ContentAsString;
finally
httpclient.Free;
end;
end;
Ошибка:
Ошибка при запросе заголовков: дескриптор находится в неправильном состоянии для запрошенной операции
Ответ №1:
В асинхронном режиме, как следует из названия, клиент выполняет запрос асинхронно в фоновом потоке.
При выполнении следующего кода происходит ContentAsString
сбой, поскольку в этот момент запрос не завершен.
output := httpclient.Get('https://google.com').ContentAsString
Если вы хотите использовать HTTP-клиент в асинхронном режиме, вам придется использовать обработчики завершения для запуска соответствующего кода после завершения запроса.
procedure TForm1.Button1Click(Sender: TObject);
var
httpclient: TNetHTTPClient;
begin
httpclient := TNetHTTPClient.Create(nil);
httpclient.Asynchronous := True;
httpclient.OnRequestCompleted := HTTPRequestCompleted;
httpclient.Get('https://google.com');
end;
procedure TForm1.HTTPRequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
var
output: string;
begin
output := AResponse.ContentAsString;
Sender.Free;
end;
Использование HTTP-клиента в асинхронном режиме, как правило, сложнее (особенно с точки зрения управления памятью), чем его использование в синхронном режиме из фонового потока.
Ниже приведен эквивалентный пример использования анонимного фонового потока:
procedure TForm1.Button1Click(Sender: TObject);
begin
TThread.CreateAnonymousThread(
procedure
var
httpclient: TNetHTTPClient;
output: string;
begin
httpclient := TNetHTTPClient.Create(nil);
try
httpclient.Asynchronous := False;
output := httpclient.Get('https://google.com').ContentAsString;
finally
httpclient.Free;
end;
end).Start;
end;
Конечно, вы также можете использовать TTask
или пользовательские потоки вместо анонимных потоков.
Комментарии:
1. Как, если хотите добавить цикл ? этот корект ? для i := от 0 до 50 начинайте //код asyn конец; конец;
2. Зависит от того, хотите ли вы делать параллельные запросы или один за другим?
3. Вы можете использовать
TParallel.amp;For
для такого цикла. TParallel.amp;Для(0, 50, процедура(I: Целое число) var httpclient… начало // ваш асинхронный код заканчивается);