Indy TCPServer 與 DataModule->ClinentDataSet->DataRequest()問題 |
答題得分者是:aftcast
|
shchen
一般會員 發表:12 回覆:27 積分:7 註冊:2003-08-13 發送簡訊給我 |
各位前輩們,小弟是用BCB,不得已在此發文求助了.
小弟做了一套MIDAS架構的資料庫系統,在上線使用一段時間了,現在遇到了需要讓其它程式設計師能與我做的Client端程式溝通操作取得資料,所以我選用了TIdTCPServer/Client 元件,在本地建立了Socket連線,讓對方的程式與我的三層架構中的Client程式交談,主要是對傳TStream 型態資料. 目前Socket 溝通及資料回傳都成功做好了,但遇到一個問題,就是在TIdTCPServer.OnExecute()事件內對於要做遠端資料查詢的動作時,就會出現 EOleException with message "CoInitialize 尚未被呼叫"的問題,如下: void __fastcall TMainForm::IdTCPServer1Execute(TIdContext *AContext) { int Result=DataModule1->ClientDataSet1->DataRequest(""); -->報錯 "CoInitialize 尚未被呼叫" if(Result==0) ...... } 若是加上CoInitialize(NULL); 又變成EOleException with message "應用程式所呼叫了整理給不同執行緒的介面" void __fastcall TMainForm::IdTCPServer1Execute(TIdContext *AContext) { CoInitialize(NULL); int Result=DataModule1->ClientDataSet1->DataRequest(""); -->報錯 "應用程式所呼叫了整理給不同執行緒的介面" if(Result==0) ...... CoUninitialize(); } 經過了詳細測試,已經可以確定,只要是在TIdTCPServer,觸發的事件中,調用DataModule1內的ClientDataSet物件,就會產生這問題,真不知道該怎麼解決唉...灰心,要重寫了, 是Colinitialize()加錯地方嗎,有誰遇過相同問題...求助.. 我的TCPServer IP是用127.0.0.1,port是設8090. 編輯記錄
shchen 重新編輯於 2011-03-26 07:33:28, 註解 無‧
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
是的,你加錯地方了
主要原因是 TCPServer的 Connection, Execute, Disconnection三個事件(請自行加on) 是給Client Thread,不是給執行程式的Main Thread,你這樣做會有兩個問題 一、存取區域的問題,你的DataModule不在你的事件中,存取到null 二、ClientDataSet不是Thread Safe物件,與Main Thread搶,它當然要殺人了 結論仍然是Thread Safe衍生的狀況 解決的辦法可以用兩種 一、用SendMessage去呼叫DataModule 二、用TIdSync物件去Synchronize VCL處理 以上
編輯記錄
GrandRURU 重新編輯於 2011-03-26 22:16:31, 註解 無‧
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
發現你的語法是bcb吧? 這裡好像是delphi…
不過我建議要不要先試一下: void __fastcall TMainForm::IdTCPServer1Execute(TIdContext *AContext) { CoInitialize(NULL); //保留 __try { m1-> 有的沒的設定 (因為是新建的,所以可能有些初始之類的,看情形 int Result=} __fianlly { delete m1; } CoUninitialize(); //保留 }
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
|
shchen
一般會員 發表:12 回覆:27 積分:7 註冊:2003-08-13 發送簡訊給我 |
沒錯,我最後也是用與你樣同的方式而成功,因為本人對的Class概念的基礎不夠,對於瞎摸試出來的方式,不知道對不對,現有你的回覆,知道方法正確的.
另外看文件,也體會,TId物件都是獨立thread的物件,不能直接呼叫主thread內的物件. ===================引 用 aftcast 文 章=================== 發現你的語法是bcb吧? 這裡好像是delphi… 不過我建議要不要先試一下: void __fastcall TMainForm::IdTCPServer1Execute(TIdContext *AContext) { CoInitialize(NULL); //保留 __try { m1-> 有的沒的設定 (因為是新建的,所以可能有些初始之類的,看情形 int Result=} __fianlly { delete m1; } CoUninitialize(); //保留 } |
shchen
一般會員 發表:12 回覆:27 積分:7 註冊:2003-08-13 發送簡訊給我 |
|
shchen
一般會員 發表:12 回覆:27 積分:7 註冊:2003-08-13 發送簡訊給我 |
不好意思,給您添煩麻了,
建議版主能不能在C Builder區內加個多層式架構的版,或將此版的版名加上"與多層式架構",例如網際網路程式與多層式架構(Muilt-tir)設計討論區(C Builder) ===================引 用 taishyang 文 章=================== 幫忙移區 ^^ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |