AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Einbinden eines Thread Downloads

Ein Thema von Stewag · begonnen am 16. Jul 2024 · letzter Beitrag vom 22. Jul 2024
 
Stewag

Registriert seit: 12. Jun 2008
180 Beiträge
 
Delphi 12 Athens
 
#11

AW: Einbinden eines Thread Downloads

  Alt 21. Jul 2024, 18:16
Danke jaenicke, aber so einfach ist es nicht.

Es fehlt schon mal der Deklarationsteil und auch der Constructor.

Habe mal versucht, das nach den Angaben von Himitsu zu ergänzen.
So bekomme ich zumindest schon mal keinen Laufzeitfehler:

Code:
unit SyncThreadedDownload;

interface

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

type
  TDownloadCompleteEvent = reference to procedure(const URL: String; Stream: TStream; Error: Exception);

  TFileDownloader = class(TThread)
    procedure ThreadedDownloadFile(const URL: String; OnDownloadComplete: TDownloadCompleteEvent);

  private
    FStream: TStream;
    FOnDownloadComplete: TDownloadCompleteEvent;

  public
    constructor Create(const URL: String; OnDownloadComplete: TDownloadCompleteEvent);
    property OnDownloadComplete: TDownloadCompleteEvent read FOnDownloadComplete write FOnDownloadComplete;

  end;

implementation

{ TFileDownloader }
constructor TFileDownloader.Create(const URL: String; OnDownloadComplete: TDownloadCompleteEvent);
begin
  if not Assigned(OnDownloadComplete) then
    raise Exception.Create('peng');
  inherited Create(False); // Himitsu: "und jetzt außen kein Start mehr, da es am Ende des Create von selbst startet" -> Äääh, wie bitte?
  FreeOnTerminate := True;
  FOnDownloadComplete := OnDownloadComplete; // Himitsu: "und der Rest im Execute/DownloadFile" -> ich glaube der Rest steckt jetzt in ThreadedDownloadFile, oder ??? 
end;

procedure TFileDownloader.ThreadedDownloadFile(const URL: String; OnDownloadComplete: TDownloadCompleteEvent);
begin
  if (URL = '') or not Assigned(OnDownloadComplete) then
    raise EArgumentException.CreateRes(@SArgumentNil);
  TThread.CreateAnonymousThread(
    procedure
    var
      HTTP: THTTPClient;
      Stream: TMemorystream;
      DError: Exception;
    begin
      TThread.NameThreadForDebugging('ThreadedDownloadFile');
      DError := nil;
      HTTP := THTTPClient.Create;
      Stream := TMemorystream.Create;
      try
        HTTP.CustomHeaders['Pragma'] := 'no-cache';
        try
          HTTP.Get(URL, Stream);
          { TThread.Synchronize(nil,
            procedure
            begin
            OnDownloadComplete(URL, Stream, nil);
            end); }
        except
          { on E: Exception do begin
            TempErr := E; // durch einen Bug muß es kopiert werden, auch wenn der Compiler sich bei OnDownloadComplete(URL, nil, E); nicht beschwert ... E ist im Sync leider NIL
            TThread.Synchronize(nil,
            procedure
            begin
            //OnDownloadComplete(URL, nil, E); // siehe Bugreport im alten QualityPotal
            OnDownloadComplete(URL, nil, TempErr);
            end);
            end; }
          FreeAndNil(Stream);
          // für das if-Assigned im OnDownloadComplete ... oder einfach lassen, auch wenn es eh nichts sinnvolles enthält, und nur auf Assigned(Error) prüfen
          DError := AcquireExceptionObject as Exception;
        end;
        TThread.Synchronize(nil,
          procedure
          begin
            OnDownloadComplete(URL, Stream, DError);
          end);
      finally
        DError.Free;
        Stream.Free;
        HTTP.Free;
      end;
    end).Start;
end;

end.
Leider klappt aber der Aufruf mit keiner der beiden angegebenen Methoden. Beide mal erhalte ich den Fehler "[dcc32 Fehler] Unit1.pas(43): E2076 Diese Form des Methodenaufrufs ist nur für Klassenmethoden oder Konstruktoren zulässig"

Code:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure DownloadComplete(const URL: String; stream: TStream; Error: Exception);

  private
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
  {Methode 1:
  TFileDownloader.ThreadedDownloadFile('https://www.example.de/test',
    procedure(const URL: String; stream: TStream; Error: Exception)
    begin
      if Assigned(stream) then
      begin // if not Assigned(Error) then
        begin
          Memo1.lines.LoadFromStream(stream);
          ShowMessage('Download complete: ' + URL);
        end;
      end;
    end);
    }
// Methode 2
   TFileDownloader.ThreadedDownloadFile('https://www.example.de/test', DownloadComplete);
end;

procedure TForm1.DownloadComplete(const URL: String; stream: TStream; Error: Exception);
begin

//Wie kann ich hier abfragen, ob eine Exception vorliegt?

    Memo1.lines.LoadFromStream(stream)
  // else
  // Label1.Text := 'Download failed';
end;
Steffen

Geändert von Stewag (21. Jul 2024 um 18:18 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz