執行緒問題 |
尚未結案
|
kkccgg
初階會員 ![]() ![]() 發表:50 回覆:54 積分:30 註冊:2002-07-28 發送簡訊給我 |
請問 :
使用Delphi5 Pro版 XP BitBtn1 : 啟動執行緒 M1 : Log執行緒 MainMenu1 : 測試操作 測試步驟及問題點 1. 按BitBtn1,啟動執行緒 2. 隨意操作MainMenu1 , 可能導致執行緒無法正常運轉也就是M1不會Log , 但在隨意Click後即又恢復正常 以上問題點不知如何事好??? Thk 以下為所有程式碼. unit main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Menus, StdCtrls, Buttons; type TWaitThread_Process = Class(TThread) private iCount:Word; { Private declarations } procedure Show_Time; protected procedure Execute;Override; public { Public declarations } Constructor Create; end; type TForm1 = class(TForm) MainMenu1: TMainMenu; A1: TMenuItem; AA11: TMenuItem; AA21: TMenuItem; Exit1: TMenuItem; T1: TTimer; LTime: TLabel; M1: TMemo; BitBtn1: TBitBtn; procedure T1Timer(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure BitBtn1Click(Sender: TObject); private bExit:Boolean; { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} Constructor TWaitThread_Process.Create; begin inherited Create(False); FreeOnTerminate:=True; End; procedure TWaitThread_Process.Execute; var Events : THandle; // 要等待的 events 陣列 TimerID : DWORD; // 計時器 ID Msg : TMsg; // 訊息結構 begin TimerID := SetTimer(0, 0, 100, nil); // 設定計時器 iCount := 0; repeat // 等待任何一個 event 被設定為 signaled, 或 WM_TIMER 來到 case MsgWaitForMultipleObjects(0, Events, False, QS_TIMER,INFINITE) of WAIT_OBJECT_0: // 收到 WM_TIMER 訊息 begin //取出 WM_TIMER 訊息 GetMessage(Msg, 0, WM_TIMER, WM_TIMER); // 進行適當處理 iCount := iCount 1; Synchronize(Show_Time); end; end; until (Terminated) or (Form1.bExit) or (iCount>=100); KillTimer(0, TimerID); // 摧毀計時器 end; procedure TWaitThread_Process.Show_Time; begin Application.ProcessMessages; Form1.M1.Lines.Add(InttoStr(iCount) ' : ' FormatDateTime('hh:nn:ss zzz',Now)); end; procedure TForm1.T1Timer(Sender: TObject); begin {顯示時間} T1.Enabled := False; LTime.Caption := FormatDateTime('hh:nn:ss zzz',Now); T1.Enabled := True; end; procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin bExit := True; //離開旗標 end; // 啟動 Thread procedure TForm1.BitBtn1Click(Sender: TObject); Var WaitThread_Process : TWaitThread_Process; begin BitBtn1.Enabled :=False; M1.Lines.Clear ; WaitThread_Process := TWaitThread_Process.Create; WaitThread_Process.WaitFor; BitBtn1.Enabled :=True; end; end. |
kkccgg
初階會員 ![]() ![]() 發表:50 回覆:54 積分:30 註冊:2002-07-28 發送簡訊給我 |
認真在Run幾次並修改發現不要執行
// 啟動 Thread procedure TForm1.BitBtn1Click(Sender: TObject); Var WaitThread_Process : TWaitThread_Process; begin BitBtn1.Enabled :=False; M1.Lines.Clear ; WaitThread_Process := TWaitThread_Process.Create; WaitThread_Process.WaitFor; BitBtn1.Enabled :=True; end;
|
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
我記得站上有Thread型的TTimer,你可以考慮用那個元件。
應該可以解決你的問題。 ===================引 用 kkccgg 文 章=================== 認真在Run幾次並修改發現不要執行WaitThread_Process.WaitFor; 即正常 但我需確認該Thread完成跳出 ?? // 啟動 Thread procedure TForm1.BitBtn1Click(Sender: TObject); Var WaitThread_Process : TWaitThread_Process; begin BitBtn1.Enabled :=False; M1.Lines.Clear ; WaitThread_Process := TWaitThread_Process.Create; WaitThread_Process.WaitFor; BitBtn1.Enabled :=True; end;
|
kkccgg
初階會員 ![]() ![]() 發表:50 回覆:54 積分:30 註冊:2002-07-28 發送簡訊給我 |
大概想知道如若不用WaitFor,如何確認Thread以執行完畢
===================引 用 kkccgg 文 章=================== 認真在Run幾次並修改發現不要執行WaitThread_Process.WaitFor; 即正常 但我需確認該Thread完成跳出 ?? // 啟動 Thread procedure TForm1.BitBtn1Click(Sender: TObject); Var WaitThread_Process : TWaitThread_Process; begin BitBtn1.Enabled :=False; M1.Lines.Clear ; WaitThread_Process := TWaitThread_Process.Create; WaitThread_Process.WaitFor; BitBtn1.Enabled :=True; end;
|
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
我覺得你的程式流程邏輯有點問題:
建議可試著改如下看是否符合你需求: 1/ 把 Application.ProcessMessages; 這行拿掉 procedure TWaitThread_Process.Show_Time; begin Form1.M1.Lines.Add(InttoStr(iCount) ' : ' FormatDateTime('hh:nn:ss zzz',Now)); end; 2/ 拿掉這二行 3/ 在thread結束前用 sendmessage 送出一個自己訂的windows 訊息, 比如說 WM_ThrdDone (我自己掰的) 4/ 在mainform 那裡實作若收到WM_ThrdDone 則 BitBtn1.Enabled :=True; 註: 關於delphi要如何使用自訂的message,請查本站一堆範例,或google一下。
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
kkccgg
初階會員 ![]() ![]() 發表:50 回覆:54 積分:30 註冊:2002-07-28 發送簡訊給我 |
謝謝您的說明.
我的用途是想把Button內Click事件改成副程式 , 並在完成該Thread後回傳某些數值 , 但若改成SendMessage那整個程序會被切割成二段 ===================引 用 aftcast 文 章=================== 我覺得你的程式流程邏輯有點問題: 建議可試著改如下看是否符合你需求: 1/ 把 Application.ProcessMessages; 這行拿掉 procedure TWaitThread_Process.Show_Time; begin Form1.M1.Lines.Add(InttoStr(iCount) ' : ' FormatDateTime('hh:nn:ss zzz',Now)); end; 2/ 拿掉這二行 3/ 在thread結束前用 sendmessage 送出一個自己訂的windows 訊息, 比如說 WM_ThrdDone (我自己掰的) 4/ 在mainform 那裡實作若收到WM_ThrdDone 則 BitBtn1.Enabled :=True; 註: 關於delphi要如何使用自訂的message,請查本站一堆範例,或google一下。 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |