關於try 與 thread 的問題 |
尚未結案
|
helper197
一般會員 發表:8 回覆:10 積分:3 註冊:2008-08-20 發送簡訊給我 |
大家好 我有3個問題想請教各位
1. 為什麼 try 有時候會無法攔截到 錯誤訊息呢? BCB有無什麼語法 可以跟 vb的 on error goto resume 依樣 可以直接把錯誤幹掉 (雖然這樣不太好) 例如: try{ RetryDataBase( MySQLDBName ); //資料庫存取 初始化 出入庫顯示於DBGrild Load_Use_WKS(); //載入需要處理的 LoadWKSTList(); //載入所有資料 CreateStatusDBG(0); //顯示目前狀態 //ScanAsrs_Details(false,true); WKS = sFun->ScanWKSBuffer(MySQLDBName,2); }catch(...){ ShowMessage("初始化失敗,關閉程式!!"); Close(); }; 但 似乎無法抓到錯誤 反而是直接跳出Error 如此在 Sock->Open() 時 也會 有用try去攔截 卻無法攔道 到 差別在於 如果有下 try 雖然不會跑 錯誤處理的地方 但至少他挑出錯誤後 按掉 可以繼續往下跑 但如果不下 try 那按掉後 他就不動 死掉了 2. //如果有出料的話 就鎖住避免重複新增資料 if(DataRuning!=false){ int OOXX = 0; //這段千萬不能拿掉 因為拿掉後 會造成 無法選擇 //原因不詳 待查 BitBtn1->Enabled = true; return; }else{ DataRuning=true; }; 上面這段程式 如果沒有加上int OOXX = 0; 那 無論 DataRuning 為 true 或 false 都會跑 BitBtn1->Enabled = true; return; 加上去之後 就會按true or false 來跑 試了 7 8次 都是這樣 也重新編譯7 8次 3. 我在一個 Command 按鈕上 //呼叫執行緒 radThread = new Run_Asrs_Details(true); radThread->Priority=tpLower; //設定優先權 radThread->Resume(); //開始啟動執行緒 在 Tread 中寫 //---- Place thread code here ---- sLogicTools *sLog = new sLogicTools; //邏輯配送Class引用 sLog->UseLogicRetrunWKSName(frmMain->MySQLDBName,frmMain->MyOracleDBName);//更新Asrs_Details delete sLog; frmMain->End_Processor (); 那這樣的話 frmMain主程式 是不是應該不會卡卡的 因為 UseLogicRetrunWKSName 副程式是在執行緒內跑?? 但位啥米 他還是會影響到主程式的介面 讓它變成 白色的 無法移動與點選 以上需要麻煩各位大大了 謝謝您 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
大家好 我有3個問題想請教各位
1. 為什麼 try 有時候會無法攔截到 錯誤訊息呢? BCB有無什麼語法 可以跟 vb的 on error goto resume 依樣 可以直接把錯誤幹掉 (雖然這樣不太好) 例如: try{ RetryDataBase( MySQLDBName ); //資料庫存取 初始化 出入庫顯示於DBGrild Load_Use_WKS(); //載入需要處理的 LoadWKSTList(); //載入所有資料 CreateStatusDBG(0); //顯示目前狀態 //ScanAsrs_Details(false,true); WKS = sFun->ScanWKSBuffer(MySQLDBName,2); }catch(...){ ShowMessage("初始化失敗,關閉程式!!"); Close(); }; 事實上它有抓到錯誤,只是你用ShowMessage是不正確的。thread裡不能用這個!! 請改用 ::MessageBox( ) 2. //如果有出料的話 就鎖住避免重複新增資料 if(DataRuning!=false){ int OOXX = 0; //這段千萬不能拿掉 因為拿掉後 會造成 無法選擇 //原因不詳 待查 BitBtn1->Enabled = true; return; }else{ DataRuning=true; }; BiBtn1 應該是主thread,即mainform上的元件,若要用它的屬性,請改用synchronize的方式。可查help,或是本站上有很多的解說。 3. 我在一個 Command 按鈕上 //呼叫執行緒 radThread = new Run_Asrs_Details(true); radThread->Priority=tpLower; //設定優先權 radThread->Resume(); //開始啟動執行緒 在 Tread 中寫 //---- Place thread code here ---- sLogicTools *sLog = new sLogicTools; //邏輯配送Class引用 sLog->UseLogicRetrunWKSName(frmMain->MySQLDBName,frmMain->MyOracleDBName);//更新Asrs_Details delete sLog; frmMain->End_Processor (); 原因如上,你用到一堆的MainForm裡的函式與元件,請用synchronize的方式 其他可參考我的部落格的thread-safe一文: http://aftcast.pixnet.net/blog/post/23786004
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
helper197
一般會員 發表:8 回覆:10 積分:3 註冊:2008-08-20 發送簡訊給我 |
嗯嗯 謝謝大大的回覆
1. 我把他改成這樣 try{ ConnectDataBase(); RetryDataBase( MySQLDBName ); Load_Use_WKS(); LoadWKSTList(); CreateStatusDBG(0); //ScanAsrs_Details(false,true); WKS = sFun->ScanWKSBuffer(MySQLDBName,2); }catch(...){ Application->MessageBox("初始化失敗,關閉程式!!",NULL, MB_OK); Close(); }; 但是 他還是跳出BCB式的錯誤訊息 說 完全沒跑 MessageBox 實在很抱歉 是我沒有說清楚 2. 不在Tread 下 只是在frmMain的一段小程式 2. 的那個問題 我猜是專案壞掉 因為我把他 放到新的專案 新的程式 舊正常@@ 至於您說3. 改放在 synchronize 可以避免吃到主程序 frmMain的資源是嗎?? 我試試看在跟您說~~ 謝謝您喔 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
不能用這個Application->MessageBox("初始化失敗,關閉程式!!",NULL, MB_OK);
要用 ::MessageBox(0,"初始化失敗,關閉程式!!",NULL, MB_OK ) ,請值接貼到你的程式中,這是win32 api。 MessageBox的前面有二個冒號,是要照抄的喔,不是我打錯! synchronize 是為了解決thread 共享資源衝突,所造成的資料錯亂。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
helper197
一般會員 發表:8 回覆:10 積分:3 註冊:2008-08-20 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
try{ }catch(...){ Close(); }; 把上面的程式改成 try{ } catch(const Exception &E) { ::MessageBox(0,"Err msg:" E.Message,NULL,MB_OK); Close(); } 這樣就可以抓到了。 (...) 是用在當錯誤超出系統可以處理的時候才進入。 至於你原始的錯誤,像是鍵值有重複之類的, 屬於資料庫裡的問題,你可能要自己查一下了!
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
helper197
一般會員 發表:8 回覆:10 積分:3 註冊:2008-08-20 發送簡訊給我 |
大大您好唷
還是無法抓到錯誤耶 我有更新畫面給您看 請參考 http://delphi.ktop.com.tw/download/upload/49437240bae8d_myerp_error.PNG 另 底下我改成這樣他才編的過@@? }catch(const Exception &E){ //(...) 是用在當錯誤超出系統可以處理的時候才進入。 //::MessageBox(0,"初始化失敗,關閉程式!!",NULL, MB_OK ); ::MessageBox(0,E.Message.c_str () ,NULL,MB_OK); Close(); }; 他似乎無法用 "Err Msg" E.Message.c_str () 放到裡面 除非用 一個變數去替代~~ 抱歉再麻煩一下了 謝謝您 PS: 至於這個錯誤是 我故意讓他 連結錯誤的 資料庫IP 讓他找不到資料庫所產生 對了 大大我是用XP BCB5.0 http://delphi.ktop.com.tw/board.php?cid=168&fid=918&tid=96475 |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
sorry,
::MessageBox(0,"Err msg:" E.Message,NULL,MB_OK); //這句話的確是錯的 就設定一個 AnsiString msg = "Err msg:" E.Message; ::MessageBox(0,msg.c_str (),NULL,MB_OK); 此外,請你試著用中斷的方式來找出是哪個function造成它錯誤的,然後把try…catch( ) 改寫在那個function裡面! 不然一時我也不知該怎麼抓了… 因為近來工作忙,沒法用太多的時間來幫你,程式細節回覆的也許有錯,請見諒! 若有他其他的前輩見到此文,也請幫忙回覆一下囉~~ 謝謝!
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2008-12-16 11:53:46, 註解 無‧
|
helper197
一般會員 發表:8 回覆:10 積分:3 註冊:2008-08-20 發送簡訊給我 |
|
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
helper197 你好,
我過去的經驗是try和catch(...)不一定能抓到所有的錯誤,尤其如果try裡面的code有其他compiler編譯的話(像呼叫到的dll或lib),常常是沒法子catch到。至今我也還是無解,如果有其他前輩有解決方法,也希望能分享給小弟知道一下。 話說回來,這個問題的根源在try裡面用到的code沒做到exception handling。比如我在try裡面呼叫了用VC寫的dll function,原則上該dll不能讓exception跑到bcb這邊的code來,一定要完全catch下來再用return的方法傳錯誤。但是如果那個dll是別人寫的....事情就難辦了... |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |