Задать вопрос
IgorPI
@IgorPI

Delphi console application async call proc?

Приветствую!

Консольное приложение.
Embarcadero® Delphi 10.3 Version 26.0.34749.6593

Создал тестовый класс, хочу сделать асинхронный вызов определённого участка кода.
Для чего мне это нужно?

Я планирую использовать конструкцию подобного рода
Http.Get(AUrl).BeforeRequest(
        procedure(AURL: string; Stream: TStream; Headers: TNetHeaders)
        begin
           // Перед запросом
        end).AfterRequest(
        procedure(ARatry: boolean; HTTPResponse: IHTTPResponse)
        var
          JsonObject: TJSONObject;
          csrfToken: string;
        begin
          JsonObject := TJSONObject.ParseJSONValue(HTTPResponse.ContentAsString(TEncoding.UTF8)) as TJSONObject;
          if JsonObject.TryGetValue('csrfToken', csrfToken) then
          begin
              // После выполнения запроса
             // ARatry = true - если нам нужно повторить запрос
            ARatry := true
          end;
        end).Success(
        procedure(Content: string)
        begin
           // Ответ сервера status code 200
        end);


Класс для достижения цели.
unit Http;

interface

uses
  System.SysUtils, System.Classes, System.Net.HttpClient, System.Net.URLClient,
  Winapi.Windows, syncobjs;

type
  THttp = class
    FBeforeRequestProc: TProc<string, TStream, TNetHeaders>;
    FAfterRequestProc: TProc<boolean, IHTTPResponse>;
    FSuccessProc: TProc<string>;
  protected
  public
    function BeforeRequest(Proc: TProc<string, TStream, TNetHeaders>): THttp;
    function AfterRequest(Proc: TProc<boolean, IHTTPResponse>): THttp;
    function Success(const Proc: TProc<string>): THttp;
    function Get(const AURL: string; const AResponseContent: TStream = nil; const AHeaders: TNetHeaders = nil): THttp;
  end;

implementation



{ THttp }

function THttp.AfterRequest(Proc: TProc<boolean, IHTTPResponse>): THttp;
begin
  FAfterRequestProc := Proc;
end;

function THttp.BeforeRequest(Proc: TProc<string, TStream, TNetHeaders>): THttp;
begin
  FBeforeRequestProc := Proc;
end;

function THttp.Get(const AURL: string; const AResponseContent: TStream; const AHeaders: TNetHeaders): THttp;
var
  Headers: TNetHeaders;
  Retry: boolean;
  Response: IHTTPResponse;
  THread: TTHread; 
begin
  Headers := AHeaders;
  THread := TTHread.CreateAnonymousThread(
    procedure
    var
     http: THttpClient;
    begin
      try
        http := THTTPClient.Create;
        FBeforeRequestProc(AURL, AResponseContent, AHeaders);
        Response := http.get(AURL, AResponseContent, AHeaders);
        FAfterRequestProc(Retry, Response);
        if Response.StatusCode = 200 then
          FSuccessProc(Response.ContentAsString(TEncoding.UTF8));
      finally
        FreeAndNil(http);
      end;
    end);
  THread.Resume;
end;

function THttp.Success(const Proc: TProc<string>): THttp;
begin
  FSuccessProc := Proc;
end;

end.


Проблема заключается в том, что при создании объекта http класса THTTPClient возникает ошибка
access violation at address write of address

Проблемный участок кода
function THttp.Get(const AURL: string; const AResponseContent: TStream; const AHeaders: TNetHeaders): THttp;
var
  Headers: TNetHeaders;
  Retry: boolean;
  Response: IHTTPResponse;
  THread: TTHread; 
begin
  Headers := AHeaders;
  THread := TTHread.CreateAnonymousThread(
    procedure
    var
     http: THttpClient;
    begin
      try
        http := THTTPClient.Create;
        FBeforeRequestProc(AURL, AResponseContent, AHeaders);
        Response := http.get(AURL, AResponseContent, AHeaders);
        FAfterRequestProc(Retry, Response);
        if Response.StatusCode = 200 then
          FSuccessProc(Response.ContentAsString(TEncoding.UTF8));
      finally
        FreeAndNil(http);
      end;
    end);
  THread.Resume;
end;
  • Вопрос задан
  • 248 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
HemulGM
@HemulGM Куратор тега Delphi
Delphi Developer, сис. админ
5dce0376cd752331096656.png

Изменения

5dce03b7d770e041230029.png

Результат

5dce041616e83598661994.png
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
IgorPI
@IgorPI Автор вопроса
Проблема в том, что главный поток завершается раньше нужного времени.
Для этого следует после
THread.Resume;
вызвать
THread.WaitFor;
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы