Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   iOS [Seattle] THttpClient - Abbruch im ReceiveData Event (https://www.delphipraxis.net/187221-%5Bseattle%5D-thttpclient-abbruch-im-receivedata-event.html)

Sir Rufo 9. Nov 2015 11:29

[Seattle] THttpClient - Abbruch im ReceiveData Event
 
Liste der Anhänge anzeigen (Anzahl: 1)
Da wollte ich so einen schönen ImageLoader basteln, der im Hintergrund das Bild lädt und dann anzeigt ...

funktioniert super unter Windows 32/64 ... aber mit iOS/OSX kann man das knicken.
Delphi-Quellcode:
procedure TForm1.ImageLoaderHttpCLientReceiveDataEvent( const Sender: TObject; AContentLength, AReadCount: Int64; var Abort: Boolean );
begin
  FImageLoader.ReportProgress( ( AReadCount * 100 ) div AContentLength );
  Abort := FImageLoader.CancellationPending; // <- Das ist der Übeltäter
end;
Wird dieses zu schnell/zu früh gesetzt, dann wird der Request einfach nicht beendet :shock:

Komplettes Beispiel im Anhang.

Gibt es da einen sinnvollen Workaround, ausser Kopfstände mit Salto rückwärts und Schraube?

RSP-12879

Union 9. Nov 2015 12:07

AW: [Seattle] THttpClient - Abbruch im ReceiveData Event
 
Hast Du es mal alternativ hiermit versucht?

Sir Rufo 9. Nov 2015 12:46

AW: [Seattle] THttpClient - Abbruch im ReceiveData Event
 
Zitat:

Zitat von Union (Beitrag 1320924)
Hast Du es mal alternativ hiermit versucht?

Jupp, das Verhalten bleibt aber gleich
Delphi-Quellcode:
{$DEFINE USE_REQUEST_VERSION}

procedure TForm1.ImageLoaderDoWorkEvent( Sender: TObject; e: TDoWorkEventArgs );
var
  url    : string;
  http   : THttpClient;
  response: IHTTPResponse;
{$IFDEF USE_REQUEST_VERSION}
  request: IHTTPRequest;
{$ENDIF}
begin
  url := e.Argument.AsString;

  http := THttpClient.Create;
  try
{$IFDEF USE_REQUEST_VERSION}
    request              := http.GetRequest( sHTTPMethodGet, url );
    request.OnReceiveData := ImageLoaderHttpCLientReceiveDataEvent;
    response             := http.Execute( request );
{$ELSE}
    http.OnReceiveData := ImageLoaderHttpCLientReceiveDataEvent;
    response          := http.Get( url );
{$ENDIF}
    e.Result := TValue.From( response );
  finally
    http.Free;
  end;
end;
Was aber auch zu erwarten war, denn
Delphi-Quellcode:
THttpClient.Get
macht intern exakt das.

Sir Rufo 9. Nov 2015 13:12

AW: [Seattle] THttpClient - Abbruch im ReceiveData Event
 
Es wird etwas besser, wenn man den ersten ReceiveData-Event erst einmal passieren lässt
Delphi-Quellcode:
procedure TForm1.ImageLoaderDoWorkEvent( Sender: TObject; e: TDoWorkEventArgs );
var
  url    : string;
  http   : THttpClient;
  response: IHTTPResponse;
begin
  url := e.Argument.AsString;

  FFirstEvent := True; // FFirstEvent setzen

  http := THttpClient.Create;
  try
    http.OnReceiveData := ImageLoaderHttpCLientReceiveDataEvent;
    response          := http.Get( url );
    e.Result := TValue.From( response );
  finally
    http.Free;
  end;
end;

procedure TForm1.ImageLoaderHttpCLientReceiveDataEvent( const Sender: TObject; AContentLength, AReadCount: Int64; var Abort: Boolean );
begin
  FImageLoader.ReportProgress( ( AReadCount * 100 ) div AContentLength );
  Abort := not FFirstEvent and FImageLoader.CancellationPending;
  FFirstEvent := False; // FFirstEvent zurücksetzen
end;
und wenn man eine Zeit-Bremse einbaut, dann geht es mit dem Stress-Test auch (weil jetzt aber auch nicht mehr gestresst wird :roll:)
Delphi-Quellcode:
procedure TForm1.ImageLoaderDoWorkEvent( Sender: TObject; e: TDoWorkEventArgs );
var
  url    : string;
  http   : THttpClient;
  response: IHTTPResponse;
begin
  url := e.Argument.AsString;

  FFirstEvent := True;
  Sleep( 500 ); // Sleeping Time

  if FImageLoader.CancellationPending
  then
    begin
      e.Cancel := True;
      Exit;
    end;

  http := THttpClient.Create;
  try
    http.OnReceiveData := ImageLoaderHttpCLientReceiveDataEvent;
    response          := http.Get( url );
    e.Result          := TValue.From( response );
  finally
    http.Free;
  end;
end;
Das sind aber genau diese seltsamen Workarounds, die ich eigentlich nicht haben möchte. Denn welche Zeitspanne muss ich denn konkret warten, damit es immer stabil funktioniert?

Da haben wir ein schönes Timing-Problem auf den OSX/iOS Plattformen. Und da es durchgängig ist, ist hier wohl die EMBA-Implementierung falsch.

Union 9. Nov 2015 13:45

AW: [Seattle] THttpClient - Abbruch im ReceiveData Event
 
Merk Dir doch die Zeit des Setzens von FFirstEvent und setze das Ende-Flag erst nach Zeitspanne x. Die ist dann sicher noch Prozessor- und OS-Versionsabhängig :freak:

Sir Rufo 9. Nov 2015 13:56

AW: [Seattle] THttpClient - Abbruch im ReceiveData Event
 
Zitat:

Zitat von Union (Beitrag 1320935)
Merk Dir doch die Zeit des Setzens von FFirstEvent und setze das Ende-Flag erst nach Zeitspanne x. Die ist dann sicher noch Prozessor- und OS-Versionsabhängig :freak:

Eben darum ist ja dieser Workaround nicht das Mittel der Wahl ... denn genau diese Zeitspanne ist das Problem.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz