Threads + IdHTTP
-
Hey @all,
und zwar da ich erst angefangen habe mit Threads zu arbeiten, ich aber noch nicht weiß wie ich das implementieren soll, frage ich Euch mal hier, ob mir jemand vielleicht einen Tip geben könnte.
Und zwar geht es um folgendes:
Ich habe ein Programm, das quasi Dateien sammelt, habe daweil maximal 10021 Dateien gehabt. Die Größe pro Datei ist ca. 70 kB. Nun ich habe es momentan so, das diese Dateien in einer Liste aufbereitet werden (Dateiname, Pfad, ...) danach wird die Liste durchgearbeitet, und bei jedem durchgang wirdIdHTTP1->Get((*listIter).full_server_path.c_str());aufgerufen. Wie sicher jeder ahnen kann, kann das bei 10021 Dateien unter Umständen ziemlich lange dauern.
Jetzt habe ich mir gedacht, dieses in Threads auszulagern, um die Dateien gleichzeitig zu downloaden.
Könnte mir da bitte jemand unterstützung geben, und mir helfen, wie ich das am besten ralisieren kann?
Lg _freeze_
-
Kann mir diesbezüglich den wirklich keiner helfen.
Lg _freeze_
-
Hallo
Hab mit Threads selber noch nicht gearbeitet, aber der BCB stellt folgendes zur verfügung : Der Eintrag zu TThread in der Hilfe, wo auch auf das Beispielprogramm unter <BCB_Path>\Examples\Apps\Threads hingewiesen wird.
Desweitern kannst du dir ein TThread-Objekt erstellen lassen : Datei/Neu.../Neu/Thread-Objekt. BCB fragt noch nach dem von dir festzulegenden Namen des Objekts, das dann automatisch von TThread abgeleitet wird.Ich mache mir aber Gedanken, ob das im Falle vom HTTP-Downloads wirklich hilft. Auf jeden Fall natülich nicht, wenn alle (oder viele) Dateien auf dem selben Server liegen. Außerdem ist zu überprüfen, ob IdHTTP mehrere Downloads gleichzeitig durchführen kann. Du müßtet wahrscheinlich für jeden Thread ein eigenes IdHTTP-Objekt erstellen und verwalten.
Und schau dir den Hinweis aus der Hilfe zu TThread an :Die Koordination zu vieler Threads verbraucht beträchtliche CPU-Zeit. Auf einem Ein-Prozessor-System stellen 16 aktive Threads die praktikable Obergrenze dar.
bis bald
akari
-
OK, ich habe es jetzt so, das in der schleife immer ein Thread aufgerufen wird.
im thread befindet sich dann ein TIdHTTP Objekt, das dynamisch erstellt und gelöscht wird (new, delete).
Das Problem was ich nun habe ist, das ich mit der Zeit einen Speicherüberlauf bekomme, und er dann
ab einen gewissen Zeitpunkt entweder 0 kbyte herunterlädt oder es zu lauter TimeOuts kommt.Hier mal der Code vom Hauptprogramm:
[cpp]
[...]
for(lfdIter = lfd.begin(); lfdIter != lfd.end(); lfdIter++) {
this->file_bytes = 0;
this->file_id++;
if(lfd.size()<=0 || this->stop_download)
break;// Building URL
string temp;
string server_path = (*lfdIter).server_path;
string tmp_url = netopt->get_protocol();
tmp_url += netopt->get_server_address() + "/";
tmp_url += check_for_slashes(server_path, true);
tmp_url += (*lfdIter).server_file;this->download_file = (*lfdIter).full_local_path.c_str();
AnsiString log1, log2;
log1.cat_sprintf("Downloading file %d/%d: %s", this->file_id, max,
(*lfdIter).full_local_path.c_str());
frmLogInfo->reLogInfo->Lines->Add(log1);new DThread2(false, Owner, (lfdIter).full_local_path.c_str(), temp_host.c_str(), tmp_url.c_str(), temp_port);
//DThread2 thread = new DThread2(false, Owner, (*lfdIter).full_local_path.c_str(), temp_host.c_str(), tmp_url.c_str(), temp_port);
//thread->WaitFor();
}
frmLogInfo->reLogInfo->Lines->Add("");
frmLogInfo->reLogInfo->Lines->Add("FINISHED");
frmLogInfo->reLogInfo->Lines->Add("");
frmLogInfo->reLogInfo->Lines->Add("--------------------------------------------------");
frmLogInfo->reLogInfo->Lines->Add("");// Save the Logfile into the Download-Directory
string logDir = this->directory;
string logfile = "";if(this->directory != "") {
check_for_slashes(logDir, false);
check_for_bslashes(logDir, true);
logfile = logDir;
}logfile = "download.log";
frmLogInfo->reLogInfo->Lines->SaveToFile(logfile.c_str());
if(frmNetwork->cbShowLogInfo->Checked == true)
frmLogInfo->Show();
else {
if(this->error_flag)
frmLogInfo->Show();
else
Application->MessageBoxA("Download complete!\nSee the log info for more information",
"FINISHED", MB_OK);
}
}
catch(GASException& e) {
Application->MessageBoxA(e.what(), e.error(), MB_OK);
}if(lfd.size() > 0)
lfd.clear();// Close the Download Progress - Window
frmProgress->Close();
[/cpp]
und hier der Thread:__fastcall DThread2::DThread2(bool CreateSuspended, AnsiString _filename, AnsiString _server, AnsiString _url, int _port) : TThread(CreateSuspended) { this->filename = _filename; this->server = _server; this->url = _url; this->port = _port; FreeOnTerminate = true; } void __fastcall DThread2::Execute() { for(frmMain->lfdIter = frmMain->lfd.begin(); frmMain->lfdIter != frmMain->lfd.end(); ++frmMain->lfdIter) { string filename2 = ""; string temp = this->filename.c_str(); if(temp.find(".") != string::npos && temp.find("\\") != string::npos) { while(temp.find("\\") != string::npos) { filename2 += temp.substr(0, temp.find("\\")+1); temp.erase(0, temp.find("\\")+1); } if(temp.find(".") != string::npos) filename2 += temp.substr(0, temp.find(".")); filename2 += ".000"; } // If this two files doesn't exist, starting Synchronize if(frmMain->netopt->check_file_exist(this->filename.c_str()) && frmMain->netopt->check_file_exist(filename2)) Synchronize(GuiSync); // If the file does allready exist, skip this file else Synchronize(GuiSync2); } } //--------------------------------------------------------------------------- void __fastcall DThread2::GuiSync() { try { IdHTTP0 = new TIdHTTP(this->object); // Using a proxy? IdHTTP0->Host = frmMain->netopt->get_server_address().c_str(); IdHTTP0->Port = 80; if(frmMain->netopt->get_use_proxy()) { IdHTTP0->ProxyParams->ProxyServer = frmMain->netopt->get_proxy_address().c_str(); IdHTTP0->ProxyParams->ProxyPort = StrToInt(frmMain->netopt->get_proxy_port().c_str()); } // Creating a new file fsDest = new TFileStream(this->filename, fmCreate); // Download the file from the server to the local file IdHTTP0->Get(this->url, fsDest); } catch(EFCreateError& e) { frmLogInfo->reLogInfo->Lines->Add(" => WARNING: The file does allready exist (ECreateError)"); } catch(EIdConnClosedGracefully& e) { // Did the file exist on the server? frmLogInfo->reLogInfo->Lines->Add(" => ERROR: This file doesn't exist on the server (EIdConnClosedGracefully)"); if(fsDest) delete fsDest; DeleteFile(this->filename.c_str()); if(frmMain->netopt->get_create_temp()) { frmLogInfo->reLogInfo->Lines->Add(" => ERROR: Creating temporary filename (*.000) (EIdConnClosedGracefully)"); string t_file = this->filename.c_str(); t_file = t_file.substr(0, t_file.find(".gif")); t_file += ".000"; fstream file(t_file.c_str(), ios::out); file.close(); } else if(!frmMain->netopt->get_create_temp()) frmLogInfo->reLogInfo->Lines->Add(" => ERROR: The file were deleted (EIdConnClosedGracefully)"); } catch(EIdHTTPProtocolException& e) { // Did the file exist on the server? frmLogInfo->reLogInfo->Lines->Add(" => ERROR: This file '" + this->filename + "'doesn't exist on the server"); if(fsDest) delete fsDest; DeleteFile(this->filename); if(frmMain->netopt->get_create_temp()) { frmLogInfo->reLogInfo->Lines->Add(" => ERROR: Creating temporary filename (*.000)"); string t_file = this->filename.c_str(); t_file = t_file.substr(0, t_file.find(".gif")); t_file += ".000"; fstream file(t_file.c_str(), ios::out); file.close(); } else if(!frmMain->netopt->get_create_temp()) frmLogInfo->reLogInfo->Lines->Add(" => ERROR: The file were deleted"); } // Delete the TIdHTTP Object if(IdHTTP0) delete IdHTTP0; // Delete the TFileStream if(fsDest) delete fsDest; } void __fastcall DThread2::GuiSync2() { frmLogInfo->reLogInfo->Lines->Add(" => WARNING: The file '" + this->filename + "' does allready exist (ECreateError)"); }Vielen DAnk im Voraus
Lg _freeze_
[edit]
Ich habe auch schon probiert, das ich z.b. 10 Dateien herunterlade. Wenn ich es im Programm statisch mache funktioniert es auch, nur leider so nicht.
Mit thread->WaitFor(); habe ich es auch schon probiert, jedoch blockiert er dann wieder das Programm, oder er schreibt mir das es ein ungültiges Handle ist (Error Code 6)