請教在執行緒中使用高精度計時器與動態陣列的問題 |
尚未結案
|
yoan4560409
一般會員 發表:11 回覆:7 積分:3 註冊:2006-08-04 發送簡訊給我 |
各位前輩好
小弟的程式基本的功能為,當執行緒執行時,會動態產生陣列,並計算值後, 開啟定時器將陣列內的值以固定時間送出,待全部送出後在清除動態產生的陣列,並關閉定時器。 目前遇到的問題是,除非我將其中的變數phase宣告成全域變數,不然無法編譯過。 但是若宣告成全域變數,第一次跑執行緒時ok,但再執行此執行緒時會有問題,因為 變數phase被delete不會再產生。 請教各位前輩 1. 我該如何將在執行緒執行時才動態產生的變數,給我的定時器函數使用? 2.或是有更好的寫法? 謝謝 [code cpp] //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" #include "Unit2.h" #include "mmsystem.h" //多媒體定時棄檔頭 #pragma package(smart_init) #define Min(x,y) ((x < y) ? x : y) #define Max(x,y) ((x > y) ? x : y) #define Accuracy 1 //最小精度 UINT TimerID; //定義定時器 int TimerAccuracy; int count=0 ; //--------------------------------------------------------------------------- __fastcall TTest::TTest(bool CreateSuspended) : TThread(CreateSuspended) { } //--------------------------------------------------------------------------- void TTest::SetName() { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = "Test"; info.dwThreadID = -1; info.dwFlags = 0; __try { RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD),(DWORD*)&info ); } __except (EXCEPTION_CONTINUE_EXECUTION) { } } //--------------------------------------------------------------------------- //---------定時器執行內容------------------ void PASCAL TimerCallProc(UINT TimerID, UINT msg,DWORD dwUser,DWORD dwa,DWORD dwb) { Form1->Edit1->Text=(String)phase[count]; //錯誤 if(count==500) { delete[] phase; //錯誤 count=0; timeKillEvent(TimerID); //刪除定時器事件 timeEndPeriod(TimerAccuracy); //清除定時器分辨率 } count ; } //--------------------------------------------------------------------------- void __fastcall TTest::Execute() { SetName(); //---- Place thread code here ---- float* phase=new float[10000]; for(int i=0;i<500;i ) phase[i]=i; TIMECAPS timecaps; if (timeGetDevCaps(&timecaps,sizeof(TIMECAPS))==TIMERR_NOERROR) //定時解析度 TimerAccuracy=Min(Max(timecaps.wPeriodMin,Accuracy),timecaps.wPeriodMax); timeBeginPeriod(TimerAccuracy); // 設定多媒體計時器的解析度 int TimerResolution=10; //設置定時間隔為10毫秒 //產生間隔10毫秒,周期執行的定時器事件;啟動定時器 TimerID = timeSetEvent(TimerResolution,TimerAccuracy,TimerCallProc,1,TIME_PERIODIC); } //--------------------------------------------------------------------------- [/code] |
lu
高階會員 發表:11 回覆:189 積分:195 註冊:2003-11-19 發送簡訊給我 |
看了一下你的程式,有一件事你要注意,『在THREAD不可以直接操作非 Thread Safe的元件』
至於什麼是非 Thread Safe的元件,一般來說畫面上的可視元件,如Edit TListBox TComboBox等都是非Thread Safe的元件 若欲知哪些是非 Thread Safe的元件,請善用站內搜尋功能,因為那又是一大篇文章 所以除非你的 timeSetEvent 有切回MainThread或有呼叫 Synchronize 不然你這種寫法是有問題低 至於為什麼不行,站內有一卡車的討論,請善用站內搜尋功能(用Thread 去搜尋) 你的問題在於,你要怎麼把 TTest::Execute() 下所產生的變數傳遞至TimerCallProc 最簡單的作法就是利用 SendMessage 在產生THREAD時順便把FORM的HANDLE傳入,如下 [code cpp] __fastcall TTest::TTest(bool CreateSuspended,Handle frmHandle) : TThread(CreateSuspended) { FormHandle = frmHandle; //用一個變數存放 Handle } struct Data_struct { UINT TimerID; UINT msg; DWORD dwUser; DWORD dwa; DWORD dwb; float* phase }; void __fastcall TTest::Execute() { //恕刪.... //用以下的CODE取代原來的timeSetEvent struct Data_struct Data; Data.TimerID = TimerResolution; Data.msg = TimerAccuracy; Data.dwUser = TimerCallProc; Data.dwa = 1; Data.dwb =TIME_PERIODIC; Data.phase = phase; SendMessage (FormHandle ,WM_USER 100,(DWORD)&Data,(DWORD)&Data); } [/code] 至於FORM對應WM_USER 100 的程式碼.....我想就不用寫了吧 當然有沒有其他的辦法~~有,只是每個人的作法不同,這部分你要多看其他人的CODE |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |