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.