全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1332
推到 Plurk!
推到 Facebook!

為什麼我的Thread會停掉...

尚未結案
jackyeh1021
一般會員


發表:7
回覆:13
積分:4
註冊:2004-03-16

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-03-02 08:31:16 IP:220.134.xxx.xxx 未訂閱
各位先進大家好:       我現在在寫一個網路攝影機的DIO偵測程式,為了要即時反映所以我採用了Thread的做法,可是每次都會跑一陣子就停止(時間不再跳動),反覆查了很久實在看不出來問題所在,各位大大可不可以幫幫忙,    
void __fastcall HTTPThread::Execute()
{
   m_hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
   http=new TNMHTTP(MyMSForm);       AnsiString strURL;
   char szURL[128];
   wsprintf(szURL,"http://10.144.111.2/axis-cgi/io/input.cgi?check=1");
   http->HeaderInfo->UserId = "root";
   http->HeaderInfo->Password = "pass";
   char ss[64];
   m_WaitTime = 500;
   while(1)
   {
       if ( WaitForSingleObject(m_hEvent,m_WaitTime/*INFINITE*/) == WAIT_TIMEOUT )
       {
            try{
                  http->Get(szURL);
            }
            catch(Exception &e)
            {
               MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
               MyMSForm->StringGrid2->Cells[2][2] = "-1";
               m_WaitTime=3000;
               continue;
            }
            char xx[64];
            int ii1,ii2=0;
            sscanf(http->Body.c_str(),"input%d=%d",&ii1,&ii2);
            iii  ;
            if(ii2==1)
            {
               MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
               MyMSForm->StringGrid2->Cells[2][2] = "1";
               iii=0;
               m_WaitTime=5000;
               continue;
            }
            if(iii>2)
            {
                MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
                MyMSForm->StringGrid2->Cells[2][2] = "0";
                iii=0;
            }
            m_WaitTime=500;
        }
        else
           break;
   }
   if(http!=NULL) delete http;
   MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
   MyMSForm->StringGrid2->Cells[2][2] = "999";
}
發表人 - jackyeh1021 於 2005/03/02 15:00:33 發表人 - jackyeh1021 於 2005/03/02 15:23:52
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-03-02 09:18:31 IP:210.68.xxx.xxx 未訂閱
您好: PO程式碼的方式請參考版歸說明 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=48259 煩請修改,謝謝您的配合< > 順心< >
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-03-02 09:20:44 IP:221.169.xxx.xxx 未訂閱
你不能在THREAD之中『直接』操作VCL喔 所謂的『直接』就是像下列的程式碼
MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
MyMSForm->StringGrid2->Cells[2][2] = "1";
站上對這類的文章有粉多人討論,建議你先利用搜尋找一下 ========================= 大家一起快樂寫程式
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-03-02 12:51:08 IP:140.112.xxx.xxx 未訂閱
jackyeh1021你好: 利用站上的系統查詢Synchronize,相信會有不少好的討論供你參考。
jackyeh1021
一般會員


發表:7
回覆:13
積分:4
註冊:2004-03-16

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-03-02 15:37:09 IP:220.134.xxx.xxx 未訂閱
親愛的版主(taishyang)大大: 不好意思,我已經修正了,不知醬可不可以, lu兄: 如果所有的thread都沒有去處理這個位置的資料,這樣也會有問題嗎? 我認為各自獨立各別的VCL,應該沒問題吧!!!
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-03-02 16:21:37 IP:221.169.xxx.xxx 未訂閱
引言: 如果所有的thread都沒有去處理這個位置的資料,這樣也會有問題嗎? 我認為各自獨立各別的VCL,應該沒問題吧!!!
你的觀念,錯得非常厲害喔 Microsoft 規定,除了在主THREAD,其他THREAD不可以『直接』操作畫面上的控制項,特別是可視元件,如果要操作你可以用Synchronize切回主THREAD操作,或是用SendMessage or PostMessage 真的建議你,先去找本MULTI THREAD的書來看,以免越寫越錯,最後連程式當在哪裡都不知 不然在K.TOP上面搜尋一下,站內有粉多相關的討論 ========================= 大家一起快樂寫程式
jackyeh1021
一般會員


發表:7
回覆:13
積分:4
註冊:2004-03-16

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-03-02 20:36:23 IP:61.231.xxx.xxx 未訂閱
感謝lu兄的指教,我也照pwipwi兄的建議看完相關的資料, 所以我已經將程式修正為以下寫法,可是還是會停止耶!! 我是不是還有地方沒考慮到....     
 
void __fastcall HTTPThread::Execute()
{
   m_hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
   http=new TNMHTTP(MyMSForm);       AnsiString strURL;
   char szURL[128];
   wsprintf(szURL,"http://10.144.111.2/axis-cgi/io/input.cgi?check=1");
   http->HeaderInfo->UserId = "root";
   http->HeaderInfo->Password = "pass";
   char ss[64];
   m_WaitTime = 500;
   while(1)
   {
       if ( WaitForSingleObject(m_hEvent,m_WaitTime/*INFINITE*/) == WAIT_TIMEOUT )
       {
            try{
                  http->Get(szURL);
            }
            catch(Exception &e)
            {
               m_strShow = "-1";
               Synchronize(ShowGrid);
               m_WaitTime=3000;
               continue;
            }
            char xx[64];
            int ii1,ii2=0;
            sscanf(http->Body.c_str(),"input%d=%d",&ii1,&ii2);
            iii  ;
            if(ii2==1)
            {
               m_strShow = "1";
               Synchronize(ShowGrid);
               iii=0;
               m_WaitTime=5000;
               continue;
            }
            if(iii>2)
            {
                m_strShow = "0";
                Synchronize(ShowGrid);
                iii=0;
            }
            m_WaitTime=500;
        }
        else
           break;
   }
   if(http!=NULL) delete http;
   m_strShow = "999";
   Synchronize(ShowGrid);
}    void __fastcall HTTPThread::ShowGrid()
{
   MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
   MyMSForm->StringGrid2->Cells[2][2] = m_strShow;    }
發表人 - jackyeh1021 於 2005/03/02 20:40:19
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-03-03 00:18:34 IP:211.76.xxx.xxx 未訂閱
jackyeh1021: 有幾個地方可能是問題所在,一個是WaitForSingleObject是不太需要的。VCL處理Multithread和MFC不太相同,混用不太好。 另一個是Execute的寫法有誤,Execute裡的要隨時檢查Terminated是否是true。如果Terminated是true就要"馬上"結束Execute()。不然Thread是不會停的。(除非你用Winapi暴力停止...)
jackyeh1021
一般會員


發表:7
回覆:13
積分:4
註冊:2004-03-16

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-03-03 10:51:43 IP:220.134.xxx.xxx 未訂閱
pwipwi兄 謝謝您的指導 不過我在http->Get(szURL);的前後設定顯示字串, 最後發現程式停在 http->Get(szURL);內就不再出來了 有各位先進有這方面的資料嗎?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-03-03 11:53:25 IP:211.76.xxx.xxx 未訂閱
引言: pwipwi兄 謝謝您的指導 不過我在http->Get(szURL);的前後設定顯示字串, 最後發現程式停在 http->Get(szURL);內就不再出來了 有各位先進有這方面的資料嗎?
和介面有關的,大多都需要Synchronize。如果不能解決再麻煩你放上程式碼吧
jackyeh1021
一般會員


發表:7
回覆:13
積分:4
註冊:2004-03-16

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-03-04 08:11:27 IP:220.134.xxx.xxx 未訂閱
我已經將Code改為這樣     
 
void __fastcall HTTPThread::Execute()
{
   m_hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
   http=new TNMHTTP(MyMSForm);       AnsiString strURL;
   char szURL[128];
   wsprintf(szURL,"http://10.144.111.2/axis-cgi/io/input.cgi?check=1");
   m_WaitTime = 500;
   while(1)
   {
       if ( WaitForSingleObject(m_hEvent,m_WaitTime/*INFINITE*/) == WAIT_TIMEOUT )
       {
            try{
                  m_strShow = "before";
                  Synchronize(ShowGrid);
                  http->Get(szURL);
                  m_strShow = "after";
                  Synchronize(ShowGrid);
            }
            catch(Exception &e)
            {
               m_strShow = "-1";
               Synchronize(ShowGrid);
               m_WaitTime=3000;
               continue;
            }
            int ii1,ii2=0;
            sscanf(http->Body.c_str(),"input%d=%d",&ii1,&ii2);
            if(ii2==1)
            {
               m_strShow = "1";
               Synchronize(ShowGrid);
               m_WaitTime=5000;
               continue;
            }
            m_strShow = "0";
            Synchronize(ShowGrid);
            m_WaitTime=500;
        }
        else
           break;
   }
   if(http!=NULL) delete http;
   m_strShow = "999";
   Synchronize(ShowGrid);
}    void __fastcall HTTPThread::ShowGrid()
{
   MyMSForm->StringGrid2->Cells[1][2] = TimeToStr(Time());
   MyMSForm->StringGrid2->Cells[2][2] = m_strShow;    }
我在http->Get(szURL);的前後設定顯示字串, 最後發現程式執行一陣子,所有的cell都顯示在before 就不動了... 所以我判斷是 TNMHTTP的問題
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-03-04 09:21:31 IP:221.169.xxx.xxx 未訂閱
jackyeh1021你好 你確定 TNMHTTP 是THREAD SAFE的嗎?    給你一個建議,除非你確定你要用的東西(特別是BORLAND 的VCL)是THREAD SAFE,你才可以用在THREAD裡面喔。    要如何確定你要用的東西是THREAD SAFE,粉簡單~~問~廠~商,天曉得,他在裡面用了什麼東西    希望對你有幫助 ========================= <>大家一起快樂寫程式
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-03-04 15:30:10 IP:221.169.xxx.xxx 未訂閱
剛剛看了一下你的程式碼發覺一件事,你的TNMHTTP沒有設定TIMEOUT時間喔 由於你是每隔 500ms 去抓取DIO的網頁,那有件事你大概沒考慮到    就是那個DEVICE可以承受那麼大量的網頁要求嗎? 偶個人保持懷疑態度    所以建議你改一下,在 http->Get(szURL); 之前加一行

http->TimeOut = 1000; 
試試看吧,希望對你有幫助 ========================= <>大家一起快樂寫程式
jackyeh1021
一般會員


發表:7
回覆:13
積分:4
註冊:2004-03-16

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-03-04 16:13:42 IP:61.220.xxx.xxx 未訂閱
親愛的lu兄: 看到您的解答,似乎看到一線曙光,不過因為即將遠行可能沒法馬上驗證,所以打算將此問題結案 pwipwi兄 感謝您的建議,因為有您所以對於thread的相關知識已經有初略的瞭解,不過因為只能將分數給其中一人,lu兄因提供了可能錯誤的地方,所以我決定將分數給他,謝謝兩位.....
系統時間:2024-05-19 19:56:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!