我目前正在将Indy的TIdHTTP
与我的Embarcadero C ++ Builder 10.1 Berlin一起使用。我已经阅读了一些有关如何使TIdHTTP
多线程的在线教程,但是主要问题是我已经在线程中测试了此组件。
这就是它的工作方式。我创建了一个线程对象,并创建了一个函数来下载该线程中的文件,显然该线程可以正常工作,并且文件已下载到我的磁盘中。但是,当我创建其他文件下载线程时,第一个线程停止。我不希望那样,我希望两个文件都可以继续同时下载(而不暂停第一个线程),就像在IDM(Internet下载管理器)中一样。
线程类类似于下面的代码:
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;
}
}
答案 0 :(得分:1)
问题在于您线程的//...
function mapDispatchToProps(dispatch) {
return {
fetchAdminSettings(organization) {
dispatch({ type: FETCH_ADMIN_SETTINGS });
firebase.database().ref(`${organization}/admin`)
.on('value', snapshot => {
dispatch({ type: FETCH_ADMIN_SETTINGS_SUCCESS, payload: snapshot.val() });
});
},
logout() {
// ...
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SettingsScreen);
方法正在WebElement web_element_found = driver.findElement(By.id("ctl00_ctl00_cphBMain_cphMain_lblObjects"));
String element_text = web_element_found.getText();
调用中完成所有工作,因此实际上所有线程的工作都在主UI线程中完成,从而序列化了下载和打破了使用工作线程的全部观点。
请勿使用Execute()
本身调用Synchronize()
。在更新UI控件时,您需要改为更改单个PutDownloadedFile()
状态事件,以使用Synchronize()
(或TIdHTTP
)。