我有一個帶有進度條和上傳xml到服務器的按鈕的表單。 按下按鈕時會創建一個新線程,該線程將創建一個套接字,然後以塊的形式將數據發送到服務器,同時它會更新進度條。 現在,當第二次按上傳按鈕時,我得到訪問衝突,並且在調試器中進度欄對象的地址爲NULL。 我不明白爲什麼進度條被釋放,所以如果任何人有任何想法,我會很感激。線程執行後進度條爲空
P.S.目標操作系統是windows PS2如果相同的代碼在主線程上運行而沒有使用線程,那麼我似乎沒有這個問題,即使我在線程中總體上忽略了進度條的使用在第一次上傳按鈕後再次設置爲空。
螺紋構造:
__fastcall UploadRouteThread::UploadRouteThread(bool CreateSuspended) : TThread(CreateSuspended)
{
this->OnTerminate = OnTerminateHandler;
ioHandlerStack = new TIdIOHandlerStack();
tcpClient = new TIdTCPClient();
tcpClient->ReadTimeout = -1;
tcpClient->UseNagle = true;
tcpClient->IOHandler = ioHandlerStack;
tcpClient->OnConnected = OnConnectedHandler;
}
的OnTerminate處理程序:
void __fastcall UploadRouteThread::OnTerminateHandler(TObject *Sender)
{
TabbedwithNavigationForm->UploadButton->Text = "Upload";
TabbedwithNavigationForm->UploadButton->Enabled = false;
TabbedwithNavigationForm->ProgressBar->Visible = false;
tcpClient->DisconnectNotifyPeer();
ShowMessage("Data uploaded.");
delete ioHandlerStack;
delete tcpClient;
TabbedwithNavigationForm->OptionButton->Enabled = true;
TabbedwithNavigationForm->RetrieveRoutesButton->Enabled = true;
TabbedwithNavigationForm->TrackButton->Enabled = true;
TabbedwithNavigationForm->MediaButton->Enabled = true;
}
Execute方法:
void __fastcall UploadRouteThread::Execute()
{
FreeOnTerminate = true;
tcpClient->Connect();
}
兩個supplumentary功能:
void __fastcall UploadRouteThread::SetHostPort(UnicodeString host, unsigned short port)
{
tcpClient->Host = host;
tcpClient->Port = port;
}
void __fastcall UploadRouteThread::SetXML(AnsiString xmlString)
{
this->xmlString = xmlString;
}
onConnect處理:
void __fastcall UploadRouteThread::OnConnectedHandler(TObject *Sender)
{
NextPacketSize nps;
TIdBytes bytes;
int chunks;
int bytesLength;
nps.PacketID = BasicPacket::DATA_UPLOAD;
nps.size = xmlString.Length();
tcpClient->IOHandler->WriteDirect(RawToBytes(&nps, sizeof(nps)), sizeof(NextPacketSize));
bytes = RawToBytes(xmlString.c_str(), xmlString.Length());
bytesLength = bytes.get_length();
chunks = ceil(float(bytesLength)/256.0);
int previousSizeSent(0);
for(int i = 1; i <= chunks; i++)
{
if(Terminated)
break;
int bytesToSend = 256;
TByteDynArray byteDynArray;
if((bytesToSend > bytesLength))
{
bytesToSend = bytesLength;
}
byteDynArray = bytes.CopyRange(previousSizeSent, bytesToSend);
tcpClient->IOHandler->WriteDirect(ToBytes(byteDynArray, byteDynArray.get_length(), 0),
byteDynArray.get_length());
sent = (float(i)/float(chunks)) * 100;
TThread::Synchronize(this, UpdateProgressBarInternal);
previousSizeSent += bytesToSend;
bytesLength -= bytesToSend;
}
}
和進度條的更新方法:
void __fastcall UploadRouteThread::UpdateProgressBarInternal()
{
if(!TabbedwithNavigationForm->ProgressBar->Visible)
{
TabbedwithNavigationForm->ProgressBar->Visible = true;
TabbedwithNavigationForm->ProgressBar->Max = 100;
}
TabbedwithNavigationForm->ProgressBar->Value = sent;
}
好吧,我會嘗試與調試,並感謝了很多的「工人」替代。我想我會這樣做,因爲它看起來比我用來管理塊的方式更清潔和易於理解(並且我認爲我的塊代碼更容易出錯:p) –
我發現了什麼是錯的...我有一個地圖組件和一個啓用或禁用GPS組件的按鈕。當gps激活gps時,它還通過使用以下代碼清除地圖以刪除標記(或者至少這是我認爲我正在做的)標記:\t \t // for(int i = 0; i < MapView-> ChildrenCount; i ++ ) \t \t // \t MapView-> Children-> ToArray()[i] - > Release();事情是它釋放了一些對象而不是標記 –