This sample utilizes the TclHttp component for downloading URLs, the TclThreadPool class for implementing the threading functionality, the TclThreadSynchronizer class for synchronizing threads with the main application thread (it is necessary for updating VCL form controls) and, finally, the TclCookieManager component.
The sample allows adding multiple download tasks to the list, start and stop them. For working in threads, the special object, TclDownloadWorkItem, is queued to the thread pool. The implementation is simple and does not require to inherit from the TThread class.
The TclDownloadInfo class keeps information about downloaded URL and its status. When you click the Stop button, the download item is marked as stopped (see the IsStop property of the TclDownloadInfo class). The IsStop property is checked inside the TclDownloadWorkItem when the OnReceiveProgress event of the TclHttp component occurs (see the DoProgress event handler method of the TclDownloadWorkItem class). This is the best way to call the Close method and interrupt the downloading of the resource. You cannot call the Close method inside the main VCL thread because the TclHttp component members are not thread-safe. This behavior is by design in order to improve the downloading speed.
Also, all created instances of the TclHttp component share the same instance of TclCookieManager. We added special TMemo control on the form for displaying cookies. This memo is updated automatically when the TclCookieManager list is changed.
procedure TForm1.AddDownload(const AURL, AFileName: string);
var
info: TclDownloadInfo;
begin
info := TclDownloadInfo.Create(AURL, AFileName);
lbDownloads.Items.AddObject(info.Display, info);
end;
procedure TForm1.StartDownloads;
var
i: Integer;
begin
for i := 0 to lbDownloads.Items.Count - 1 do
begin
if (TclDownloadInfo(lbDownloads.Items.Objects[i])).Status = dsReady then
begin
FThreadPool.QueueWorkItem(TclDownloadWorkItem.Create
(TclDownloadInfo(lbDownloads.Items.Objects[i]), clCookieManager1));
end;
end;
end;
procedure TclDownloadWorkItem.Execute(AThread: TThread);
var
http: TclHttp;
stream: TStream;
begin
try
http := nil;
stream := nil;
try
http := TclHttp.Create(nil);
http.CookieManager := FCookies;
stream := TFileStream.Create(FInfo.FileName, fmCreate);
http.Get(FInfo.URL, stream);
finally
stream.Free();
http.Free();
end;
except
//ChangeStatus(dsError);
end;
end;
Article ID: 63, Created: July 16, 2013 at 11:54 PM, Modified: March 17, 2020 at 1:38 PM