Klar gerne, ich hab hier bei der 'Arbeit' aber kein Delphi zum testen, daher alle Angaben ohne Gewähr
Jeder Thread sollte sein eigenes TIdHTTP-Objekt haben, was sich doppelt positiv auswirkt. Keine Zugriffsverletzungen mehr, weil Thread und Formular nicht aufeinander zugreifen und flüssige Programmausführung trotz Blocking Sockets. Durch die Verwendung von Blocking Sockets werden auch keine unnötigen, zusätzlichen Threads erzeugt.
Delphi-Quellcode:
type
TDownloadThread = class(TThread)
private
Downloader: TIdHTTP; //Thread-Eigener Downloader
procedure CustomOnWork(Sender: TObject; AThread: TIdConnectionThread; AWorkCount: Cardinal); {Hat evtl anders formulierte Parameter}
public
Aborted: Boolean;
constructor Create(CreateSuspended: Boolean = false);
destructor Destroy; override;
procedure Execute; override;
end;
implementation
{TDownloadThread}
constructor TDownloadThread.Create(CreateSuspended: Boolean = false);
begin
inherited Create(true);
Aborted := false;
//Eigenen Downloader erzeugen
Downloader := TIdHTTP.Create;
with Downloader do
begin
//Einstellungen ändern (Connect Timeouts usw..)
{...}
//Eigene OnWork Methode mit Abbruchsmöglichkeit zuweisen
OnWork := CustomOnWork;
end;
{Habe Thread erstmal Suspended erstellt, weil ich nicht sicher bin, ob sonst sofort Execute aufgerufen wird - evtl korrigieren}
If not CreateSuspended then Resume;
end;
procedure CustomOnWork(Sender: TObject; AThread: TIdConnectionThread; AWorkCount: Cardinal);
begin
If Aborted then AThread.Connection.Disconnect;
end;
destructor TDownloadThread.Destroy;
begin
Downloader.Free;
end;
procedure TDownloadThread.Execute;
begin
try
Downloader.Get(SomeURL);
except
DeleteFile(SomeFile);
end;
end;
Edit: Um die hässlichen Zugriffsverletzungen beim Beenden zu unterbinden musst du im OnClose bzw. OnCloseQuery alle Threads terminieren (und warten, bis sie terminiert sind). Ich hab es damals so gelöst, dass beim ersten Klick auf close die Threads "freundlich" zum terminieren aufgefordert werden ( MyThread.Terminate ). Und beim zweiten mal hart terminiert werden (TerminateThread(MyThread.Handle)). Zusätzich kannst du auf
WM_QUERYENDSESSION mit hartem terminieren reagieren.
Dani H.