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
 
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.962 Beiträge
 
Delphi 12 Athens
 
#12

AW: Einbinden eines Thread Downloads

  Alt 21. Jul 2024, 21:21
Danke jaenicke, aber so einfach ist es nicht.
Doch, wäre es, wenn du nicht selbst noch etwas dazu schreiben würdest. Das Beispiel war vollständig. Ich hatte nur den Inhalt der Prozedur weggelassen, weil der oben eh schon stand. Komplett sieht es dementsprechend so aus:
Delphi-Quellcode:
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);

procedure ThreadedDownloadFile(const URL: String; OnDownloadComplete: TDownloadCompleteEvent);

implementation

procedure 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;
      Success: Boolean;
      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.
Wenn du es als Klasse nutzen möchtest, kannst du das natürlich tun (finde ich auch besser), aber dann brauchst du eine Klassenmethode:
Delphi-Quellcode:
unit SyncThreadedDownload;

interface

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

type
  TFileDownloader = class
  private
    type
      TDownloadCompleteEvent = reference to procedure(const URL: String; Stream: TStream; Error: Exception);
  public
    class procedure ThreadedDownloadFile(const URL: String; OnDownloadComplete: TDownloadCompleteEvent);
  end;

implementation

class 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;
      Success: Boolean;
      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.
Wie kann ich hier abfragen, ob eine Exception vorliegt?
Das stand oben im Quelltext als Kommentar drin:
Zitat:
if not Assigned(Error) then
Sebastian Jänicke
AppCentral
  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 21:16 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