В настоящее время я использую TIdHTTP
из Indy с моим Embarcadero C ++ Builder 10.1 Berlin.Я прочитал несколько онлайн-уроков о том, как сделать TIdHTTP
многопоточным, но главная проблема в том, что я уже тестировал этот компонент в потоке.
Так вот как он работает.Я создал объект потока и создал функцию для загрузки файла в этом потоке, очевидно, что поток работает нормально, и файл загружается на мой диск.Но когда я создаю дополнительные потоки для загрузки файлов, первый поток останавливается.Я не хочу этого, я хочу, чтобы оба файла продолжали загружаться одновременно (без остановки первого потока), как в IDM (Internet Download Manager).
Класс потока, как в кодениже:
class TIdHTTPThread : public TThread
{
protected:
void __fastcall Execute();
void __fastcall PutDownloadedFile();
public:
__fastcall TIdHTTPThread(bool CreateSuspended);
void __fastcall IdHTTPBeginWork(TObject *ASender, TWorkMode AWorkMode,
__int64 AWorkCountMax);
void __fastcall IdHTTPWork(TObject *ASender, TWorkMode AWorkMode,
__int64 AWorkCount);
void __fastcall IdHTTPEndWork(TObject *ASender, TWorkMode AWorkMode);
void __fastcall DownloadFile(UnicodeString AFileURL, UnicodeString AFileDest);
void __fastcall CreateQueue(TWinControl* wcParent, TAlign alAlign);
private:
TIdHTTP* IdHTTP;
TMemoryStream* msMemoryStream;
UnicodeString uFileURL;
UnicodeString uFileDest;
int iDownProgress;
int iFileSize;
int iMaxProgress;
int iDownSpeed;
TWinControl* wcParent;
TIFDQueue *ifdQueue;
};
Пожалуйста, не беспокойтесь о дополнительных свойствах и методах в классе, я просто хочу добиться того, что мне нужно в моем вопросе.
Файл CPP:
void __fastcall TIdHTTPThread::CreateQueue(TWinControl* wcParent, TAlign alAlign)
{
this->wcParent = wcParent;
ifdQueue = new TIFDQueue(this->wcParent, alAlign);
}
void __fastcall TIdHTTPThread::IdHTTPBeginWork(TObject *ASender, TWorkMode AWorkMode,
__int64 AWorkCountMax)
{
this->iFileSize = AWorkCountMax;
this->iMaxProgress = AWorkCountMax;
ifdQueue->SetFileSize(this->iFileSize);
ifdQueue->SetMaxProgress(this->iMaxProgress);
ifdQueue->SetFileURL(this->uFileURL);
ifdQueue->SetFilePath(this->uFileDest);
ifdQueue->OnBeginUpdate();
}
void __fastcall TIdHTTPThread::IdHTTPWork(TObject *ASender, TWorkMode AWorkMode,
__int64 AWorkCount)
{
this->iDownProgress = AWorkCount;
this->iDownSpeed = AWorkCount / 1024;
ifdQueue->SetDownProgress(this->iDownProgress);
ifdQueue->SetDownSpeed(this->iDownSpeed);
ifdQueue->OnWorkUpdate();
}
void __fastcall TIdHTTPThread::IdHTTPEndWork(TObject *ASender, TWorkMode AWorkMode)
{
ifdQueue->OnEndUpdate();
this->Terminate();
}
//**//
void __fastcall TIdHTTPThread::DownloadFile(UnicodeString AFileURL, UnicodeString AFileDest)
{
this->uFileURL = AFileURL;
this->uFileDest = AFileDest;
}
void __fastcall TIdHTTPThread::PutDownloadedFile()
{
try {
this->msMemoryStream = new TMemoryStream;
this->IdHTTP = new TIdHTTP(NULL);
this->IdHTTP->OnWorkBegin = this->IdHTTPBeginWork;
this->IdHTTP->OnWork = this->IdHTTPWork;
this->IdHTTP->OnWorkEnd = this->IdHTTPEndWork;
this->IdHTTP->ConnectTimeout = 20000;
this->IdHTTP->ReadTimeout = 60000;
this->IdHTTP->Get(this->uFileURL, this->msMemoryStream);
this->msMemoryStream->SaveToFile(this->uFileDest);
} __finally {
delete this->msMemoryStream;
delete this->IdHTTP;
}
}
__fastcall TIdHTTPThread::TIdHTTPThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall TIdHTTPThread::Execute()
{
//---- Place thread code here ----
FreeOnTerminate = true;
Synchronize(&this->PutDownloadedFile);
}
//---------------------------------------------------------------------------
ОБНОВЛЕНИЕ:
void __fastcall TIdHTTPThread::PutDownloadedFile()
{
try {
this->CookieManager = new TIdCookieManager(NULL);
this->SSLIOHandlerSocket = new TIdSSLIOHandlerSocketOpenSSL(NULL);
this->msMemoryStream = new TMemoryStream;
// Configure SSL IOHandler
this->SSLIOHandlerSocket->SSLOptions->Method = sslvSSLv23;
this->SSLIOHandlerSocket->SSLOptions->SSLVersions = TIdSSLVersions() << sslvTLSv1_2 << sslvTLSv1_1 << sslvTLSv1;
// Setup HTTP
this->IdHTTP = new TIdHTTP(NULL);
this->ifdQueue->StopDownload(this->IdHTTP); // Function To stop download When Fired (doesn't fire imidiatly)
this->IdHTTP->OnWorkBegin = this->IdHTTPBeginWork;
this->IdHTTP->OnWork = this->IdHTTPWork;
this->IdHTTP->OnWorkEnd = this->IdHTTPEndWork;
this->IdHTTP->OnRedirect = this->IdHTTPRedirect;
this->IdHTTP->HandleRedirects = true;
this->IdHTTP->AllowCookies = true;
this->IdHTTP->CookieManager = this->CookieManager;
this->IdHTTP->IOHandler = this->SSLIOHandlerSocket;
this->IdHTTP->Get(this->uFileURL, this->msMemoryStream);
if ( this->msMemoryStream->Size >= this->IdHTTP->Response->ContentLength ) {
this->msMemoryStream->SaveToFile(this->uFileName);
}
} __finally {
delete this->msMemoryStream;
delete this->CookieManager;
delete this->SSLIOHandlerSocket;
delete this->IdHTTP;
}
}