各位大侠,一个有关多线程方面的问题,查阅了大量书籍,可还是没有找到答案。 |
答題得分者是:jow
|
treachery
一般會員 發表:5 回覆:3 積分:1 註冊:2007-10-01 發送簡訊給我 |
由于线程里牵扯到VCL控件的调用,因此无法使用CreatThread函数。
因此只能使用Delphi的THhread类实现,实现是实现了,可是现在碰到一个辣手的问题。 创建并激发线程代码放在了一个按钮里,代码如下: [code delphi] var a:LoadServerCommandTread; begin a:=LoadServerCommandTread.Create(false); [/code] 这样可以创建并运行线程是没错,但是,每次启动线程前没有办法知道线程是否在运行,用GetExitCodeThread放在 a:=LoadServerCommandTread.Create(false);获取线程状态,任何时候线程的状态都是已运行。这样一来造成的问 题是,用户如果点N次按钮,那么就有N个同样的线程运行,就造成了一个相当混乱的状况。 找了不少资料,似乎都没有牵扯这个,是因为过于简单,我没有想通,还是怎么的。希望知道的朋友能告诉我,谢谢了。
------
跳舞吧,如同没有任何人注视你一样; 唱歌吧,如同没有任何人聆听一样; 去爱吧,如同从来没有受过伤害一样; 工作吧,如同不需要金钱一样; 活着吧,如同今天是末日一样; ----艾佛烈德.德索萨 |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
(1)以下測試程式碼在D7撰寫, TThread在D6與D7下有些差異, 請參考這一篇:
http://delphi.ktop.com.tw/board.php?cid=30&fid=69&tid=90452 (2)要辨識所產生多個執行緒, 你可以在Create執行緒時, 以參數帶入可資判斷的資訊 如 ID. (3)或以Event方式, 在執行緒運作過程中, 將它的狀態傳出 以下測試碼, 僅供參考... [code delphi] unit fMain; interface uses Windows, Classes, SysUtils, Forms, StdCtrls, Controls, ExtCtrls; type { TMyThread } TLabelUpdatedEvent = procedure(Sender: TObject; ID: string; Counting: Integer) of object; TMyThread = class(TThread) private FOwner: TForm; FID: string; FLabel: TLabel; FOnLabelUpdated: TLabelUpdatedEvent; protected Counting: Integer; procedure Execute; override; procedure Update; public constructor Create(AOwner: TForm; ID: string); destructor Destroy; override; property ID: string read FID; property OnLabelUpdated: TLabelUpdatedEvent read FOnLabelUpdated write FOnLabelUpdated; end; { TForm1 } TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private List: TStringList; procedure DO_ON_Terminated(Sender: TObject); procedure DO_ON_LabelUpdate(Sender: TObject; ID: string; Counting: Integer); public end; var Form1: TForm1; implementation [/code] [code delphi] implementation {$R *.dfm} { TMyThread } constructor TMyThread.Create(AOwner: TForm; ID: string); begin inherited Create(True);//Suspend thread execution FreeOnTerminate := False; FOwner := AOwner; FID := ID; FLabel := TLabel.Create(nil); FLabel.Left := Random(FOwner.Width-FLabel.Width); FLabel.Top := Random(FOwner.Height-FLabel.Height); FLabel.Parent := AOwner; Resume; //Resume thread execution end; destructor TMyThread.Destroy; begin FreeAndNil(FLabel); // inherited;//在D7中, 加call inherited 會產生Exception end; procedure TMyThread.Execute; begin Counting := 1000; while not Terminated and (Counting > -1) do begin Synchronize(Update); Application.ProcessMessages; Sleep(10); Dec(Counting); end; Terminate; end; procedure TMyThread.Update; begin if Assigned(FLabel) then begin FLabel.Caption := IntToStr(Counting); FLabel.Font.Color := RGB(Random($100),Random($100),Random($100)); FLabel.Update; if Assigned(FOnLabelUpdated) then FOnLabelUpdated(Self, FID, Counting); end; end; //------------------------------------------------------------------------------ procedure TForm1.Button1Click(Sender: TObject); var ID: string; Index: Integer; T: TMyThread; begin if Assigned(List) then begin ID := IntToStr(Random(MaxInt)); if not List.Find(ID, Index) then begin T := TMyThread.Create(Self, ID); T.OnTerminate := DO_ON_Terminated; T.OnLabelUpdated := DO_ON_LabelUpdate; Index := List.AddObject(ID, T); end; Caption := Format('New Thread = %d, %s', [Index, ID]); end; end; procedure TForm1.FormCreate(Sender: TObject); begin List := TStringList.Create; List.Sorted := True; end; procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose := Assigned(List) and (List.Count = 0); if CanClose then FreeAndNil(List); end; procedure TForm1.DO_ON_LabelUpdate(Sender: TObject; ID: string; Counting: Integer); var S: string; begin S := Format('%s, %d', [ID, Counting]); ListBox1.Items.Add(S); if ListBox1.Count = 20 then ListBox1.Items.Delete(0); ListBox1.Update; end; procedure TForm1.DO_ON_Terminated(Sender: TObject); var T: TMyThread; Index: Integer; begin if Assigned(Sender) and (Sender is TMyThread)then begin T := TMyThread(Sender); if Assigned(List) and List.Find(T.ID, Index) then List.Delete(Index); T.Free; end; end; end. [/code] |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |