MyronJovy
@MyronJovy

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

私は中国出身です。これは Delphi の THttpClient ライブラリに関する質問です。

解決したいこと

ネットワークから切断されているときに要求をテストすると、System.Net.HttpClient ライブラリが例外をスローするのはなぜですか?しかし、ネットワークに再接続すると、例外がまだ発生しました。これにより、インターネットから切断された状態でリクエストを試行することになります。失敗した場合は、ネットワークに再接続したときにアプリケーションを再起動して正常に接続することしかできません。誰かこれを解決するのを手伝ってくれませんか?

発生している問題・エラー

image.png

code

unit HttpUnit;

interface

uses
  System.Net.HttpClient, System.Net.URLClient, System.Types, System.SysUtils,
  System.Classes;

type
  THttp = class

  public

    class procedure DownloadToStream(const AUrl: string;
      const AStream: TStream);
  private

    class var FClient: THTTPClient;
    class var FRequest: IAsyncResult;
    class procedure DoEndDownload(const AsyncResult: IAsyncResult);
  end;

implementation

class procedure THttp.DownloadToStream(const AUrl: string;
  const AStream: TStream);

begin
  FClient := THTTPClient.Create;
  try
    // 发起异步请求并传递回调方法
    FRequest := FClient.BeginGet(DoEndDownload, AUrl, AStream);
  except
    on E: Exception do
      writeln('Error during request: ', E.Message);
  end;
end;

class procedure THttp.DoEndDownload(const AsyncResult: IAsyncResult);
var
  LAsyncResponse: IHTTPResponse;
begin
  // 确保异步操作完成
  try
    writeln('Request received.');
    LAsyncResponse := THTTPClient.EndAsyncHTTP(AsyncResult);

    if AsyncResult.IsCancelled then
      writeln('Download Canceled')
    else
    begin
      writeln('Download Finished!');
      writeln(Format('Status: %d - %s', [LAsyncResponse.StatusCode,
        LAsyncResponse.StatusText]));
    end;
  except
    on E: Exception do
    begin
      writeln('Error during asynchronous request: ', E.Message);
    end;

  end;

end;

end.
0

1Answer

Download は http通信が非同期で行われるので、直接 例外を受け取ることができないためだと思います。
回避策の一例としては、Download前に、同期でhttp-getを行って正常に通信できるかを確かめる方法があります。

function CheckHttpGet(const url: string): boolean;
uses System.Net.HttpClient;
var
  http: THTTPClient;
  response: IHTTPResponse;
  stream: TSTringStream;
  stringList : TStringList;
begin
  http := THTTPClient.Create;
  stream := TStringStream.Create;
  stringList := TStringList.Create;
  try
    try
      response := http.Get(url, stream);
      stringList.LoadFromStream(response.ContentStream, TEncoding.UTF8);
      result := true;
    except
      result := false;
    end;
  finally
    stringList.Free;
    stream.Free;
    http.Free;
  end;
end;

const
  checkURL = 'https://....';
  downloadURL = 'https://....';

begin

  if CheckHttpGet(checkURL) then
    http.DownloadToStream(downloadURL, outputStream)

  else
    OutputDebugString('network not available.');

end;

1Like

Comments

  1. @MyronJovy

    Questioner

    これは素晴らしい解決策です、ありがとう!

  2. もし解決したようであれば、当Q&Aをクローズしてください。

Your answer might help someone💌