請問 Idftp 與 Timer 關係 |
答題得分者是:RaynorPao
|
maped
一般會員 ![]() ![]() 發表:13 回覆:19 積分:6 註冊:2008-10-06 發送簡訊給我 |
Dear all,
我的 Indy 為 9.0.18 版,環境:BCB 6.0 版, 然後純粹上傳一個檔案, 在上傳之前開啟一個Timer 來顯示一個進度表的畫面,之後會有別的用途 但是timer一直都無法進入, void __fastcall TForm1::Button1Click(TObject *Sender) { String str, str1; Timer1->Enabled = true; OpenDialog1->Execute(); str = OpenDialog1->FileName.c_str(); str1 = ExtractFileName(str); IdFTP1->Put(str, str1); } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { CGauge1->Progress = ((CGauge1->Progress 1) % CGauge1->MaxValue); Application->ProcessMessages(); } 程式碼就以上而已,在上傳過程中,timer都進不去, 請問大家這樣Timer可以進入嗎? 因為我的Timer都無法進入,直到傳完為止才可以進入, 不曉得有什麼地方有誤呢? 謝謝大家。 |
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
(1)在沒有其他特殊的原因為前題,以下的程式碼是可以正常運作的,給你參考看看:
[code cpp] long glFileSize=0; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Timer1->Enabled=false; Timer1->Interval=100; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { OpenDialog1->InitialDir=ExtractFilePath(Application->ExeName); if(OpenDialog1->Execute() && FileExists(OpenDialog1->FileName)) { IdFTP1->Host=FTP_SERVER; IdFTP1->Username=FTP_USERNAME; IdFTP1->Password=FTP_PASSWORD; Timer1->Enabled=true; try { IdFTP1->Connect(true, 3000); IdFTP1->Put(OpenDialog1->FileName, ExtractFileName(OpenDialog1->FileName)); IdFTP1->Disconnect(); } catch(Exception &ex) { ShowMessage(ex.Message); } } } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { Label1->Caption=IntToStr(CGauge1->Progress); } //--------------------------------------------------------------------------- void __fastcall TForm1::IdFTP1WorkBegin(TObject *Sender, TWorkMode AWorkMode, const int AWorkCountMax) { glFileSize=AWorkCountMax; } //--------------------------------------------------------------------------- void __fastcall TForm1::IdFTP1Work(TObject *Sender, TWorkMode AWorkMode, const int AWorkCount) { CGauge1->Progress=(double)AWorkCount/(double)glFileSize*100; Application->ProcessMessages(); } //--------------------------------------------------------------------------- [/code] (2)不過你曾經在這篇文章(http://delphi.ktop.com.tw/board.php?cid=168&fid=920&tid=95520)裡面提到,「如果用無線傳輸且訊號微弱時,程式都會一直停留,無法到下一行去」,因為我的環境無法模擬出你所說的情況,因此我不確定以上的程式碼,在你所說的情況發生時,是否還可以正常的運作,如果還是不行的話,可能真的要認真考慮改用 Thread 的作法了
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
編輯記錄
RaynorPao 重新編輯於 2008-10-14 23:20:10, 註解 無‧
|
maped
一般會員 ![]() ![]() 發表:13 回覆:19 積分:6 註冊:2008-10-06 發送簡訊給我 |
感謝 RaynorPao 版主還記得我提過的問題,
經過測試後發現,當正常情形下,也就是它的傳輸是OK的話,Timer會在傳輸的間隔中進去, 舉例來說,若是一筆資料要傳十次才傳完,也就是說10% , 20%, 30% ....100%,那Timer會在每傳完10%的時候進去, 但是在傳下一個10%過程就不會進去, 也就是說我即使設 timer 50ms進去一次,但是timer進去的次數大約也是一秒才進去, 因為假設間隔的時間只能讓timer進去一次的話,到我傳到100%時,timer裡的cnt也只有10而已, 但是這樣剛好呼應我之前提的問題,就是它如果一段10%都一直傳不完的話,那這樣Timer不就永遠進不去嗎? 不曉得是不是這樣呢? |
RaynorPao
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
(1)根據我自己做實驗的結果,理論上應該是像你所說的,我想...原因可能是因為原本 Timer 是使用 Main Thread 來達成,而 IdFTP 佔用了 Main Thread,而因此讓 Timer 無法正常的運作,不過這是我個人的猜測,還沒有得到驗證
(2)所以我建議你先把程式改成以下這個樣子,然後在你所說的環境下做個實驗,然後觀察 Memo 裡面的時間數據,或許可以「間接」驗證 (1) 的想法 [code cpp] long glFileSize=0; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Timer1->Enabled=false; Timer1->Interval=50; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { OpenDialog1->InitialDir=ExtractFilePath(Application->ExeName); if(OpenDialog1->Execute() && FileExists(OpenDialog1->FileName)) { IdFTP1->Host=FTP_SERVER; IdFTP1->Username=FTP_USERNAME; IdFTP1->Password=FTP_PASSWORD; Memo1->Lines->Clear(); Memo1->Lines->Add("Start"); Timer1->Enabled=true; try { IdFTP1->Connect(true, 3000); IdFTP1->Put(OpenDialog1->FileName, ExtractFileName(OpenDialog1->FileName)); IdFTP1->Disconnect(); } catch(Exception &ex) { ShowMessage(ex.Message); } Memo1->Lines->Add("End"); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { SYSTEMTIME st; GetLocalTime(&st); Memo1->Lines->Add(IntToStr(st.wYear) "-" IntToStr(st.wMonth) "-" IntToStr(st.wDay) ", " IntToStr(st.wHour) ":" IntToStr(st.wMinute) ":" IntToStr(st.wSecond) ":" IntToStr(st.wMilliseconds)); } //--------------------------------------------------------------------------- void __fastcall TForm1::IdFTP1WorkBegin(TObject *Sender, TWorkMode AWorkMode, const int AWorkCountMax) { glFileSize=AWorkCountMax; } //--------------------------------------------------------------------------- void __fastcall TForm1::IdFTP1Work(TObject *Sender, TWorkMode AWorkMode, const int AWorkCount) { CGauge1->Progress=(double)AWorkCount/(double)glFileSize*100; Application->ProcessMessages(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button4Click(TObject *Sender) { Timer1->Enabled=false; } //--------------------------------------------------------------------------- [/code] (3)不過如果驗證 (1) 的結果成立的話,那也代表在你所說的環境裡面,目前看來...似乎用 Timer 並無法配合,在沒有想到其他合適的辦法之前,可能只能用 Thread 來實作了
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
編輯記錄
RaynorPao 重新編輯於 2008-10-15 19:05:19, 註解 無‧
|
maped
一般會員 ![]() ![]() 發表:13 回覆:19 積分:6 註冊:2008-10-06 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |