線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2883
推到 Plurk!
推到 Facebook!

關於try 與 thread 的問題

尚未結案
helper197
一般會員


發表:8
回覆:10
積分:3
註冊:2008-08-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-12-13 13:39:05 IP:59.112.xxx.xxx 訂閱
大家好  我有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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-12-13 15:10:17 IP:122.120.xxx.xxx 訂閱
大家好  我有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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-12-13 15:26:57 IP:59.112.xxx.xxx 訂閱
嗯嗯 謝謝大大的回覆

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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-12-13 15:53:02 IP:122.120.xxx.xxx 訂閱
不能用這個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
編輯記錄
aftcast 重新編輯於 2008-12-13 15:54:04, 註解 無‧
aftcast 重新編輯於 2008-12-13 15:55:47, 註解 無‧
helper197
一般會員


發表:8
回覆:10
積分:3
註冊:2008-08-20

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-12-13 16:30:05 IP:59.112.xxx.xxx 訂閱
大大您好:


我把您的 ::Msgbox 加上去了 但還是發生錯誤

我把圖節給您看 再麻煩您幫我看一下了

謝謝

圖的位置
http://delphi.ktop.com.tw/download/upload/49437240bae8d_myerp_error.PNG


PS: 會發生這錯誤是我故意打錯 來試試看結果滴
編輯記錄
helper197 重新編輯於 2008-12-13 16:30:34, 註解 無‧
helper197 重新編輯於 2008-12-13 16:31:45, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-12-14 00:12:42 IP:122.120.xxx.xxx 訂閱

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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-12-14 09:23:34 IP:59.112.xxx.xxx 訂閱
大大您好唷

還是無法抓到錯誤耶


我有更新畫面給您看 請參考 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
編輯記錄
helper197 重新編輯於 2008-12-14 09:24:53, 註解 無‧
helper197 重新編輯於 2008-12-14 09:38:26, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-12-16 11:49:17 IP:210.64.xxx.xxx 訂閱
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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-12-16 22:08:23 IP:59.112.xxx.xxx 訂閱
嗯嗯  我了解  

大家都很忙 我也是都工作到很晚

我後來 在那個Function會發生錯誤的


sDS->Actuve = true 上 加了 try~catch

他已經會跳出Msgbox 的視窗囉

只是 還是會先跳出 Error 才 跳出這個Msgbox

目前這個問題 不大 我在研究看看 我想應該是我在bcb上的設定有問題

才造成他無法隱藏掉那個訊息

謝謝您唷~~~
pwipwi
版主


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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2009-01-24 02:33:07 IP:118.168.xxx.xxx 訂閱
helper197 你好,
我過去的經驗是try和catch(...)不一定能抓到所有的錯誤,尤其如果try裡面的code有其他compiler編譯的話(像呼叫到的dll或lib),常常是沒法子catch到。至今我也還是無解,如果有其他前輩有解決方法,也希望能分享給小弟知道一下。
話說回來,這個問題的根源在try裡面用到的code沒做到exception handling。比如我在try裡面呼叫了用VC寫的dll function,原則上該dll不能讓exception跑到bcb這邊的code來,一定要完全catch下來再用return的方法傳錯誤。但是如果那個dll是別人寫的....事情就難辦了...
系統時間:2024-11-23 3:25:02
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!