![]() |
AW: Einbinden eines Thread Downloads
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:
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"
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.
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; |
AW: Einbinden eines Thread Downloads
Zitat:
Delphi-Quellcode:
Wenn du es als Klasse nutzen möchtest, kannst du das natürlich tun (finde ich auch besser), aber dann brauchst du eine Klassenmethode:
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.
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. Zitat:
Zitat:
|
AW: Einbinden eines Thread Downloads
D-A-N-K-E Himitsu und jaenicke!!! :-D
"Manchmal ist es gar nicht kaputt, man ist nur zu blöd!" |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:05 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