全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2071
推到 Plurk!
推到 Facebook!

執行緒問題

尚未結案
kkccgg
初階會員


發表:50
回覆:54
積分:30
註冊:2002-07-28

發送簡訊給我
#1 引用回覆 回覆 發表時間:2011-01-13 23:19:18 IP:111.255.xxx.xxx 訂閱
請問 :

使用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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2011-01-14 00:06:57 IP:111.255.xxx.xxx 訂閱
認真在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;
GrandRURU
站務副站長


發表:234
回覆:1651
積分:1742
註冊:2005-06-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2011-01-14 13:55:40 IP:203.75.xxx.xxx 未訂閱
我記得站上有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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2011-01-15 00:52:07 IP:111.255.xxx.xxx 訂閱
大概想知道如若不用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
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2011-01-17 10:54:18 IP:210.64.xxx.xxx 訂閱
我覺得你的程式流程邏輯有點問題:
建議可試著改如下看是否符合你需求:
1/ 把 Application.ProcessMessages; 這行拿掉
procedure TWaitThread_Process.Show_Time;
begin
Application.ProcessMessages;
Form1.M1.Lines.Add(InttoStr(iCount) ' : ' FormatDateTime('hh:nn:ss zzz',Now));
end;

2/ 拿掉這二行
WaitThread_Process.WaitFor;
BitBtn1.Enabled :=True;

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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2011-01-17 11:38:54 IP:111.255.xxx.xxx 訂閱
謝謝您的說明.

我的用途是想把Button內Click事件改成副程式 , 並在完成該Thread後回傳某些數值 ,
但若改成SendMessage那整個程序會被切割成二段



===================引 用 aftcast 文 章===================
我覺得你的程式流程邏輯有點問題:
建議可試著改如下看是否符合你需求:
1/ 把 Application.ProcessMessages; 這行拿掉
procedure TWaitThread_Process.Show_Time;
begin
Application.ProcessMessages;
Form1.M1.Lines.Add(InttoStr(iCount) ' : ' FormatDateTime('hh:nn:ss zzz',Now));
end;

2/ 拿掉這二行
WaitThread_Process.WaitFor;
BitBtn1.Enabled :=True;

3/ 在thread結束前用 sendmessage 送出一個自己訂的windows 訊息, 比如說 WM_ThrdDone (我自己掰的)
4/ 在mainform 那裡實作若收到WM_ThrdDone 則 BitBtn1.Enabled :=True;

註: 關於delphi要如何使用自訂的message,請查本站一堆範例,或google一下。
系統時間:2017-10-23 17:48:17
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!